One way to do what you want is with two config file, and and in the first line of your main() function, add:
putenv(“OPENSSL_CONF=/path/to/your/conf”) depending on whether you want to run in FIPS mode or not. Of course, this only works if FIPS is needed application wide, not on a per connection basis. If running in FIPS mode, I would also call: EVP_set_default_properties(NULL, “fips=yes”); > On Oct 23, 2021, at 9:58 AM, Jason Schultz <[email protected]> wrote: > > Quick aside: I know the 3.0 FIPS module is not "approved" yet, I'm just > trying to get my application updates done in advance. > > I’m porting an application from OpenSSL 1.1.1, which was originally written > for OpenSSL 1.0.2, to OpenSSL 3.0. Going to 3.0, I need to incorporate FIPS > usage. My Linux application basically is told if its user wants to use FIPS > or not. We don’t use the cryptographic APIs (EVP_*), we just need to create > an SSL_CTX, and SSL objects created with SSL_new() based on this SSL_CTX, > which will then call SSL_read(), SSL_write(), etc. The application won’t > “fetch” any algorithms. So my focus can been on Section 7.7 of the Wiki: > > https://wiki.openssl.org/index.php/OpenSSL_3.0#Using_the_FIPS_module_in_SSL.2FTLS > > <https://wiki.openssl.org/index.php/OpenSSL_3.0#Using_the_FIPS_module_in_SSL.2FTLS> > > > Based on if FIPS is on or off, I will use the replacement for SSL_CTX_new() > and call SSL_CTX_new_ex() either something like this: > > ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method()); > > or this: > > ctx = SSL_CTX_new_ex(fips_libctx, NULL, TLS_method()); > > Depending on if the users does not want FIPS, or wants FIPS, respectively. > > Based on that and what Section 7.7 tells me, I know I need: > > A non-default library context with the FIPS provider loaded (called > fips_libctx), and > A non-default library context with the default provider loaded (called > non_fips_libctx) > > I know that I don’t want all applications using OpenSSL to use the FIPS > module by default, so I’m just trying to configure mine correctly, using the > APIs (and possibly config files). I also obviously don’t want to make my > application use the FIPS module only. > > Given all of the above I’m confused on how to set up #1 and #2. It seems like > I need to use a combination of configuration files and programmatically > calling APIs in my application. In the Wiki and the fips_module man page > there is a section called “Programmatically loading the FIPS module > (nondefault library context)”. I’m pretty sure this is what I want. The code > example says it “assumes the existence of a config file called > openssl-fips.cnf that automatically loads and configures the FIPS and base > providers.” > > The .cnf files that I have after the (FIPS) install of OpenSSL 3.0 are in > /usr/local/ssl/: openssl.cnf and fipsmodule.cnf. > > I guess the first thing is I’m confused on if the “openssl-fips.cnf” file > referred to in the example is in addition to the two files above, or a > replacement for one of them, and also what the contents of it need to be. > > I had already made changes to the openssl.cnf file for FIPS (described in > earlier sections of the Wiki): > > # For FIPS > # Optionally include a file that is generated by the OpenSSL fipsinstall > # application. This file contains configuration data required by the OpenSSL > # fips provider. It contains a named section e.g. [fips_sect] which is > # referenced from the [provider_sect] below. > # Refer to the OpenSSL security policy for more information. > .include /usr/local/ssl/fipsmodule.cnf ß uncommented > > [openssl_init] > providers = provider_sect > > # List of providers to load > [provider_sect] > default = default_sect > # The fips section name should match the section name inside the > # included fipsmodule.cnf. > fips = fips_sect ß uncommented > > # If no providers are activated explicitly, the default one is activated > implicitly. > # See man 7 OSSL_PROVIDER-default for more details. > # > # If you add a section explicitly activating any other provider(s), you most > # probably need to explicitly activate the default provider, otherwise it > # becomes unavailable in openssl. As a consequence applications depending on > # OpenSSL may not work correctly which could lead to significant system > # problems including inability to remotely access the system. > [default_sect] > activate = 1 ß uncommented > > I did this to make sure the FIPS provider was available and make sure the > default provider was activated. > > I also changed the fipsmodule.cnf file to comment out the activate = 1 line: > > [fips_sect] > # activate = 1 > conditional-errors = 1 > security-checks = 1 > module-mac = > E4:0D:C8:C3:1E:DB:2B:30:E6:F2:49:7B:F5:BD:10:5C:9A:2B:CC:C1:33:49:31:B5:C5:AF:50:AB:82:1E:AE:C9 > > > That was from the “Programmatically loading the FIPS module (default library > context)” section, so I’m wondering if this was a mistake. > > But currently, with the configs files as described above, my application is > loading both providers: > > fipsp = OSSL_PROVIDER_load(NULL, "fips"); > if (fipsp == NULL) > { > /* error handling */ > } > > defp = OSSL_PROVIDER_load(NULL, "default"); > if (defp == NULL) > { > /* error handling */ > } > > And then creating two library contexts: > > fips_libctx = OSSL_LIB_CTX_new(); > non_fips_libctx = OSSL_LIB_CTX_new(); > > Which are later used to create SSL_CTX’s as needed: > > if (user does not want fips) > { > ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method()); > } > else (user wants fips) > { > ctx = SSL_CTX_new_ex(fips_libctx, NULL, TLS_method()); > } > > But I think the 2nd to last step is probably creating two library contexts, > both using fips because of my changes to the default configuration file. > (more on my changes to the default file later) Looking at section 7.5 of the > Wiki, I’m thinking I need to create a file called openssl-fips.cnf with the > contents something like(or maybe a minimum of): > > [fips_sect] > activate = 1 > conditional-errors = 1 > security-checks = 1 > module-mac = > E4:0D:C8:C3:1E:DB:2B:30:E6:F2:49:7B:F5:BD:10:5C:9A:2B:CC:C1:33:49:31:B5:C5:AF:50:AB:82:1E:AE:C9 > > [base_sect] > activate = 1 > > Then before creating SSL_CTX’s and after the OSSL_LIB_CTX() calls, I need to > call: > > OSSL_LIB_CTX_load_config(fips_libctx, “openssl-fips.cnf”); > > Which will get the FIPS and base providers in the fips_libctx. The > non_fips_libctx will use the default config file and have the default > provider, which is what I want. > > Also, it seems like I need to call: > > defctxnull = OSSL_PROVIDER_load(NULL, “null”); > > Which is to “prevent anything from using the default library context”? > > Also, I probably need to revert my changes to the default config file to not > activate additional providers, which means only the default one will be > activate implicitly. Then the non_fips_libctx = OSSL_LIB_CTX_new(); line will > set up the default provider in non_fips_libctx. > > I’m hoping someone can point me in the right direction, because the other > problem is that I’m not sure how to validate what I’ve done is correct. As > in, how do I know fips_libctx is actually “FIPS” compliant, and/or the > SSL_CTX’s I create are “FIPS”. I realize there are probably several ways to > do this, but I’m looking to isolate my application only this way, and not > affect any other applications on the system. > > Thanks in advance. > > Jason
