Author CristiFati
Recipients CristiFati
Date 2016-07-22.18:02:21
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1469210543.94.0.196720087995.issue27592@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2016-07-22 18:02:24CristiFatisetrecipients: + CristiFati
2016-07-22 18:02:23CristiFatisetmessageid: <1469210543.94.0.196720087995.issue27592@psf.upfronthosting.co.za>
2016-07-22 18:02:23CristiFatilinkissue27592 messages
2016-07-22 18:02:22CristiFaticreate