This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: FIPS_mode() and FIPS_mode_set() functions in Python (ssl)
Type: enhancement Stage: resolved
Components: Versions: Python 3.4
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: CristiFati, alex, christian.heimes, dstufft, giampaolo.rodola, janssen, pitrou, r.david.murray
Priority: normal Keywords: patch

Created on 2016-07-22 18:02 by CristiFati, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
Python-3.4.4-ssl_fips.patch CristiFati, 2016-07-22 18:02
Messages (6)
msg271006 - (view) Author: Cristi Fati (CristiFati) * Date: 2016-07-22 18:02
During last years, the FIPS mode, has become more and more popular, especially in US (probably because it was "promoted" by government institutions).
All OpenSSL versions (didn't check 1.0.0 or lower since they're no longer supported), have the "basic FIPS functionality", even if built without openssl-fips module. By "basic FIPS functionality", I mean the 2 functions:
- `int FIPS_mode(void)` - used to get the current FIPS mode (for non FIPS openssl, it simply returns 0)
- `int FIPS_mode_set(int r)` - used to set the current FIPS mode in the currently loaded libcrypto/libeay32 (for non FIPS openssl it sets the openssl error: "error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported")

The goal of this patch is to add the 2 functions in Python (3.4.4 source tarball) - ssl (and _ssl) module - in order to be able to control FIPS mode from within a Python process (I am aware that some platforms allow setting FIPS at a global level, but this offers more granularity).

The patch is simple, for the getter it simply returns the OpenSSL function value, while for the setter it doesn't return anything but throws an exception if some error occurs.

Note0 (about how do I set the error): `_setSSLError(ERR_error_string(ERR_get_error(), NULL) , 0, __FILE__, __LINE__);` as opposed to the regular way: `_setSSLError(NULL, 0, __FILE__, __LINE__);`. I didn't use the whole make_ssl_data.py mechanism because:
- 1 - it binds against the OpenSSL version used at compile time
 - 1.1 - on Ux (where Python modules are dynamically linked to OpenSSL), if compiling against one OpenSSL version and at runtime another (newer) version which defines new functionality (and new error codes) is present, if one of those newer errors is encountered, the error message won't be as complete: "ssl.SSLError: fips mode already set (_ssl.c:3763)" as opposed to "ssl.SSLError: error:2D078072:FIPS routines:FIPS_module_mode_set:fips mode already set (_ssl.c:3763)"
 - 1.2 - on Win (where Python modules are statically linked to OpenSSL), there won't be such a problem. However, regarding static linking (this is not related to this post), this is not a scalable solution (now if only _ssl and _hashlib link to OpenSSL, it's __sort of__ OK, but if another one, or more will be added it won't be), so dynamic linking should be used, although that comes with its problems. 2 possible ways to solve them:
  - 1.2.1 - simply dynamic link to OpenSSL and at runtime it will fail importing the modules; this will happen a lot since (as opposed to Ux), I think that there's a 90%+ chance that no OpenSSL is installed on a Win machine
  - 1.2.2 - dynamic link to OpenSSL and also redistribute the OpenSSL dlls (although I didn't check what this would mean from licensing PoV). This would also raise the problem of precedence: which dlls should be used by default if an OpenSSL version is installed on the machine.
- 2 - It is simpler (here I might be missing something). To me it seems cleaner to delegate the job to (runtime) OpenSSL instead of make_ssl_data.py and the logic from `fill_and_set_sslerror` (which could be removed in the future, I'd say).

Note1: The whole thing could also be applied to hashlib (simply copy the changes from ssl.py to hashlib.py - to have as less duplicate code as possible), but since due to hashlib caching, changing the FIPS mode on the fly won't be reflected in the possibility/impossibility of using a hash (e.g. `md5`), I figured that it doesn't worth the effort. As a workaround, for someone who really needs to set it, they can do it from ssl.
msg271008 - (view) Author: Alex Gaynor (alex) * (Python committer) Date: 2016-07-22 18:09
I'm opposed to adding FIPS knobs to Python's SSL module for a few reasons:

- FIPS is a bad standard (which I'm happy to talk at length about)
- OpenSSL is regularly on the verge of dropping FIPS support (https://www.openssl.org/blog/blog/2016/07/20/fips/ is the most recent rescue from the brink of removal)
- It further ties us to the OpenSSL API, in favor of being a more general purpose SSL API.
msg271015 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-22 19:48
See also issue 9216 and issue 9146.  Even if we wanted to do it it sounds like it isn't quite as easy as allowing the mode to be set.

I'm inclined to agree with Alex, since he's the expert.  Especially since it *is* possible to set it from outside the process.
msg271025 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2016-07-22 20:02
I second Alex's statement, too.

Am 22. Juli 2016 21:48:20 MESZ, schrieb "R. David Murray" <report@bugs.python.org>:
>
>R. David Murray added the comment:
>
>See also issue 9216 and issue 9146.  Even if we wanted to do it it
>sounds like it isn't quite as easy as allowing the mode to be set.
>
>I'm inclined to agree with Alex, since he's the expert.  Especially
>since it *is* possible to set it from outside the process.
>
>----------
>nosy: +r.david.murray
>
>_______________________________________
>Python tracker <report@bugs.python.org>
><http://bugs.python.org/issue27592>
>_______________________________________
msg271026 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-22 20:09
Heh, I should have said "an" expert.  With two weighing in I think I'll close this.

Thanks for the contribution, though.  Sorry we aren't going to make use of it.
msg271036 - (view) Author: Cristi Fati (CristiFati) * Date: 2016-07-22 21:27
Thank you all for chiming in (so quickly). I did this in 2013 (maybe back then the situation was different), and have successfully used it since.

Regarding comments:
 - Alex:
   1: I'm not an expert, so I'm not going to argue with it. However I thought that if it's enforced by the government (and NIST) it would make sense. Nowadays I get this feeling that when it comes to security, people tend to lose their technical common sense and implement stuff without questioning.
   2: I've just read Steve Marquess's post (and a couple of others linked from it) and I'm a little bit surprised since the FIPS funcs have been added to OpenSSL stating with version 1.0.* and they're about to be removed. Anyway, there are IT mammoths that have deals with the government (big bucks deals - involving FIPS) and use OpenSSL as a cryptography and secure socket provider (personally I consider those corporations that make use of open source software in order to get millions and give nothing back, parasites). I think when OpenSSL will publicly announce the FIPS drop, they'll will have nothing to do but chip in, as it will be extremely difficult to switch to other providers (if any - I've seen Bladelogic name mentioned,I'm not sure it will cover, also for Java apps there was RSA or EMC, which is also going out of support).
   3: This is a good point, since there's no other alternative (that I know of), that uses/doesn't use FIPS.

 - David: bug9216 - the patch from RedHat (`usedforsecurity` parameter for md5 hash), I'm using it for 3 years; I didn't encounter the 2nd one. But both apply to hashlib. Reagrding ssl, changing FIPS mode would make a difference, e.g. when creating secure connections with certificates with (now considered weak anyway) md5 hash algorithms.

Thanks everyone for reviewing.
History
Date User Action Args
2022-04-11 14:58:34adminsetgithub: 71779
2016-07-22 21:27:03CristiFatisetmessages: + msg271036
2016-07-22 20:09:51r.david.murraysetstatus: open -> closed
resolution: rejected
messages: + msg271026

stage: resolved
2016-07-22 20:02:59christian.heimessetmessages: + msg271025
2016-07-22 19:48:20r.david.murraysetnosy: + r.david.murray
messages: + msg271015
2016-07-22 18:09:46alexsetnosy: + janssen, pitrou, giampaolo.rodola, christian.heimes, alex, dstufft
messages: + msg271008
2016-07-22 18:02:23CristiFaticreate