Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] How to use openssl/3.2.1 with the FIPS module from openssl/3.0.8 #22796

Open
gegles opened this issue Feb 17, 2024 · 17 comments
Open
Labels
question Further information is requested

Comments

@gegles
Copy link
Contributor

gegles commented Feb 17, 2024

What is your question?

We are trying to create a FIPS compliant app. For that, we want to use the latest openssl/3.2.1 package via self.requires("openssl/3.2.1") but we also need to package the FIPS module (i.e. fips.so or fips.dll or fips.dylib) from the officially supported version, i.e. openssl/3.0.8. See the official OpenSSL doc:

Please follow the Security Policy instructions to download, build and install a validated OpenSSL FIPS provider. 
Other OpenSSL Releases MAY use the validated FIPS provider, but MUST NOT build and use their own FIPS provider. 
For example you can build OpenSSL 3.2 and use the OpenSSL 3.0.8 FIPS provider with it.

My initial solution (that sorta works) was the following:

    def build_requirements(self):
        # FIPS
        # Note: Ideally, this should be a `self.requires` in `requirements`.
        # This openssl will be built with the `build` profile when ideally it should be built with the `host` profile
        self.tool_requires(f"openssl/3.0.8")

    def requirements(self):
        self.requires("openssl/3.2.1")  # Only explicitly needed to extract the openssl executable

    def generate(self):
        # Get fips shared library
        openssl_fips = self.dependencies.build["openssl"]
        openssl_mod_dir = openssl_fips.runenv_info.vars(self)["OPENSSL_MODULES"]
        build_lib_dir = os.path.join(self.build_folder, "lib", str(self.settings.build_type), "ossl-modules")
        copy(self, "fips.*", openssl_mod_dir, build_lib_dir)
        ...

This sorta works, except for when cross-compiling (i.e. macOS Silicon -> Intel). Indeed, the fips module will be of the build arch type (armv8) instead of the host arch type (x86_64).

Ideally, it would be great if we could somehow self.requires() 2 different versions of the same package, but that might be tricky.

Otherwise, is there a way (as part of the conanfile.py and using simple methods) to merely download a separate version of a package and extract what's needed out of it?

@gegles gegles added the question Further information is requested label Feb 17, 2024
@gegles
Copy link
Contributor Author

gegles commented Feb 17, 2024

@gegles
Copy link
Contributor Author

gegles commented Mar 28, 2024

@uilianries @RubenRBS @grafikrobot @Hopobcn @Croydon @jcar87, I know your busy, but any thoughts on this? Thx!

@grafikrobot
Copy link
Contributor

I have no idea about openssl.

@gegles
Copy link
Contributor Author

gegles commented Mar 28, 2024

I have no idea about openssl.

I hear you, but this is actually a bit broader than openssl See:

Ideally, it would be great if we could somehow self.requires() 2 different versions of the same package, but that might be tricky.

Otherwise, is there a way (as part of the conanfile.py and using simple methods) to merely download a separate version of a package and extract what's needed out of it?

I guess my point is, there are rare cases (like this one), when it may be warranted to self.requires() 2 versions of the same package....
Is there a safe/elegant way of providing this capability?

@Croydon
Copy link
Contributor

Croydon commented Mar 28, 2024

Your workaround with using one as a build_requirement and one as a requirement is probably the only way currently, everything else needs a change in Conan itself.

But why would you ever mix two different versions of OpenSSL in one build? If you care about FIPS then you care about certification, why would you want to use a non-certificate version at the same time in the same application?

@gegles
Copy link
Contributor Author

gegles commented Mar 28, 2024

But why would you ever mix two different versions of OpenSSL in one build? If you care about FIPS then you care about certification, why would you want to use a non-certificate version at the same time in the same application?

Thanks @Croydon! My understanding (coming from our internal security expert @kulkarniamit) is that, for the FIPS certification to be valid, one must use the exact version of the fips module (i.e. fips.dll or fips.so) and code that has been certified (i.e. v3.0.8). For the rest of the openssl libs/executables, the latest (i.e. v3.2.x) can (and probably should) be used.

Thinking about it, another approach could be to allow for some kind of recipe "alias". In other words, we could have an openssl-fips or openssl-fips-module recipe (that only includes the FIPS certified versions of openssl)...

This way, we could have the following:

def requirements(self):
        self.requires("openssl/3.2.1")
        self.requires("openssl-fips/3.0.8")

This could be an elegant way to solve this whole thing, but at the conan center level and just for that specific openssl-related situation.

Would you guys be open to that? I could work on a PR...

That alias recipe could do more or less... 1) It could literally just be pointing back to the openssl recipe, maybe with just version restrictions. Or 2) It could only bundle the fips .dll/.so/.dylib ...

LMK. Thanks!

@gegles
Copy link
Contributor Author

gegles commented Mar 28, 2024

After a quick googling, it appears that both 3.0.8 and 3.0.9 have now been FIPS validated. But this also re-emphasize the fact that all the others are not.

@kulkarniamit
Copy link

The FIPS Provider contains a subset of the algorithm implementations available in the default provider. The FIPS Provider only includes algorithms that have been FIPS 140-2 validated, while the default provider includes a broader set of algorithms.
OpenSSL documentation recommends an approach that allows using latest release of OpenSSL 3.x with OpenSSL 3.0.8 (also 3.0.9) FIPS provider.

So, the combination of using the OpenSSL 3.0.8 FIPS Provider along with the latest OpenSSL 3.x can provide the following benefits for applications:

  • FIPS Compliance: Using FIPS 140-2 validated cryptographic module allows applications to meet regulatory requirement
  • Comprehensive Algorithm Support: The combination of FIPS Provider and latest default provider will provide a broad range of modern, secure cryptographic algorithms to applications out-of-the-box.
  • Flexibility and Configurability: Applications can choose to use the FIPS Provider, the default provider, or even load additional providers as needed to meet their specific security and algorithm requirements.
  • Ongoing Maintenance and Security Updates: The default provider receives regular maintenance and security updates from the OpenSSL development team, ensuring applications have access to the latest bug fixes and security improvements.
  • Mitigation of Vulnerabilities: Having a latest default provider helps with mitigations and patches for latest CVEs as seen here

@gegles
Copy link
Contributor Author

gegles commented Mar 28, 2024

Ok, I've done a quick/rough PoC for a possible way to address this. Check it out and let me know. thx!

@Croydon
Copy link
Contributor

Croydon commented Mar 29, 2024

FIPS Compliance: Using FIPS 140-2 validated cryptographic module allows applications to meet regulatory requirement

Aren't you losing this aspect in the very moment, where you are adding and using regular-non-FIPS OpenSSL components?

@gegles
Copy link
Contributor Author

gegles commented Mar 29, 2024

@Croydon, I hear what you're saying.. (and agree), but, somehow this seems to be the recommended practice by the OpenSSL devs. See here for an example (back when only 3.0.0 was FIPS and the latest non-FIPS was 3.0.8).

@kulkarniamit may be able to provide better pointers from the docs...

gegles added a commit to gegles/conan-center-index that referenced this issue Mar 29, 2024
This removes some hardcoded names and allows for the package to be "renamed" more easily...

For example if one wanted to create a distinct `openssl-fips` package so as to use it in conjunction with the standard `openssl` package without any collision.

See conan-io#22796 for more context
gegles added a commit to gegles/conan-center-index that referenced this issue Mar 29, 2024
This removes some hardcoded names and allows for the package to be "renamed" more easily...

For example if one wanted to create a distinct `openssl-fips` package so as to use it in conjunction with the standard `openssl` package without any collision.

See conan-io#22796 for more context
@gegles
Copy link
Contributor Author

gegles commented Mar 29, 2024

@Croydon, see my minor tweak/improvement here to the openssl recipe.
With this, I am able to have a bare minimum recipes/openssl-fips folder that simply points back to the recipes/openssl
With this config.yaml:

versions:
  # Note: Only ever add the versions of OpenSSL that have been FIPS certified
  3.0.9:
    folder: "../openssl/3.x.x"
  3.0.8:
    folder: "../openssl/3.x.x"

This allows me to run the following command:

conan create -b missing --version 3.0.9 --name openssl-fips ../openssl/3.x.x

It all works, but with a key issue... for this to work I to do two things:

  • Comment out the name = openssl in the main recipe
  • Use --name openssl-fips in the create command

Obviously, some package name customization mechanism would need to be provided by the conan center... i.e. it could either pick up the name from the folder name (when not specified in the recipe) or from the config.yaml maybe?

Overall, I believe this whole mechanism would be very low effort, have no redundancy in the recipe definition (there would still only be one openssl recipe) and it does beautifully address exactly this "unusual" requirement from the OpenSSL package...

Any thoughts?

@kulkarniamit
Copy link

FIPS Compliance: Using FIPS 140-2 validated cryptographic module allows applications to meet regulatory requirement

Aren't you losing this aspect in the very moment, where you are adding and using regular-non-FIPS OpenSSL components?

FIPS provider in OpenSSL 3 is a dynamically loadable provider. Applications can offer a switch/option to enable/disable FIPS provider offering a choice between FIPS approved implementations and regular non-fips components. This would allow users to switch between fips and default provider (non-fips) implementations based on their regulatory compliance requirements.
Adding a regular non-fips openssl provider does not make the application non-compliant. Using a non-fips implementation makes it non-compliant. So, the application must have strict controls to ensure FIPS approved implementations are used when FIPS switch is turned on.
Shipping a default provider (3.x) with a FIPS provider (3.0.8/3.0.9) allows this flexibility for applications to switch based on user requirement.

gegles added a commit to gegles/conan-center-index that referenced this issue Mar 31, 2024
This removes some hardcoded names and allows for the package to be "renamed" more easily...

For example if one wanted to create a distinct `openssl-fips` package so as to use it in conjunction with the standard `openssl` package without any collision.

See conan-io#22796 for more context
gegles added a commit to gegles/conan-center-index that referenced this issue Apr 20, 2024
This removes some hardcoded names and allows for the package to be "renamed" more easily...

For example if one wanted to create a distinct `openssl-fips` package so as to use it in conjunction with the standard `openssl` package without any collision.

See conan-io#22796 for more context
gegles added a commit to gegles/conan-center-index that referenced this issue Apr 26, 2024
This removes some hardcoded names and allows for the package to be "renamed" more easily...

For example if one wanted to create a distinct `openssl-fips` package so as to use it in conjunction with the standard `openssl` package without any collision.

See conan-io#22796 for more context
@jcar87
Copy link
Contributor

jcar87 commented Apr 26, 2024

It may be possible for the openssl recipe itself to have logic like this - and more closely follow the instructions:

https://github.com/openssl/openssl/blob/master/README-FIPS.md#installing-the-fips-provider-and-using-it-with-the-latest-release

The below snipped does address the issue that you mentioned about the host context.

class OpenSSLConan(ConanFile):
    name = "openssl"
    version = "3.2.1"

    def requirements(self):
          if self.options.use_validated_fips:
               self.requires("openssl/3.0.8", visible=False, libs=False, headers=False, run=False)
               
    def package(self):
         self.run("make install:)
         
         # copy fips module from the openssl/3.0.8 dependency into the package foler

I believe the FIPS certification involves some sort of testing to validate it's working properly, this would have to be done both at package time (with wrap.pl and make test as advised in the OpenSSL documentation, as well as the test_package. Ensuring that this process passes would be the responsibility of the users.

This involves the openssl recipe depending on an earlier version of itself, in a way that is visible only to itself and does not propagate nor pollute the build process. If this doesn't currently work we are exploring the possibility of addressing this in the next Conan 2 release. There's some questions around option propagation that we need to consider, which also reinforces the notion of running the tests at package time and the consumer test in test_package.

This would avoid having to make further changes to the recipe/cmake, in particular the complexity surrounding having two references from the same recipe file. If this is something that can be fixed in the recipe with Conan features, let's do it :D

@gegles
Copy link
Contributor Author

gegles commented Apr 26, 2024

Yes, I like this a lot and I do think it would be the most elegant, logical and easiest way to provide the openssl package with the proper FIPS module... Thx!

@jcar87
Copy link
Contributor

jcar87 commented Apr 26, 2024

Thanks @gegles - thank you for providing details and for experimenting with this, it's been really helpful.

@jcar87
Copy link
Contributor

jcar87 commented Apr 26, 2024

@gegles -

We are experimenting with the feature on this branch: https://github.com/conan-io/conan/pull/16132/files memsharded:feature/require_bootstrap

If you are willing to try it out, you can probably install it in a python virtual environment with

pip install git+https://github.com/memsharded/conan.git@feature/require_bootstrap

Key points:

  • when requiring the "earlier" version of the same reference, it must have visible=False, but also all the other traits should be disabled (the ones in my example above are probably enough)
  • in order to be exposed to the package_folder of the "older" openssl, you need to use the self.dependencies interface, docs here: https://docs.conan.io/2/reference/conanfile/methods/generate.html#conan-conanfile-model-dependencies - it will probably be something like self.dependencies["openssl'].package_folder
  • if I remember correctly, in order to create a package from source that requires itself, you may need to pass --build="missing:openssl/*"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants