Open gegles opened 6 months ago
FYI @uilianries @RubenRBS @grafikrobot @Hopobcn @Croydon @jcar87
@uilianries @RubenRBS @grafikrobot @Hopobcn @Croydon @jcar87, I know your busy, but any thoughts on this? Thx!
I have no idea about openssl.
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?
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?
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!
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.
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:
Ok, I've done a quick/rough PoC for a possible way to address this. Check it out and let me know. thx!
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?
@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...
@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:
name = openssl
in the main recipe--name openssl-fips
in the create commandObviously, 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?
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.
It may be possible for the openssl
recipe itself to have logic like this - and more closely follow the instructions:
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
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!
Thanks @gegles - thank you for providing details and for experimenting with this, it's been really helpful.
@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:
visible=False
, but also all the other traits should be disabled (the ones in my example above are probably enough)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
--build="missing:openssl/*"
Does anyone have some working prototype? I wonder how override/force will work in case of several versions.
Does anyone have some working prototype? I wonder how override/force will work in case of several versions.
@Nekto89, I haven't gotten around to write that updated recipe with the use_validated_fips
option. Feel free to implement it as per @jcar87's suggestion ;-)
You bring up a good point... I guess override/force would change the main version of the package, but the version of the validated fips used would remain the same "hardcoded" 3.0.8 ...
@Nekto89 see here for my first attempt to solve this.
Just for history: I've tried changes in PR on MSVC. For version override I had to add [replace_requires] to host profile because it's not clear how to do that through conanfile.py which already has "main openssl version". Zlib requirements of 3.0.9 can't be overriden without replace_requires too. I have slightly customized recipe that allows me to replace zlib with zlib-ng.
def requirements(self):
self.requires("openssl/3.0.14@user/channel#4faa23d318801e3887bc428ace1f8e4d", force=True)
self.requires("zlib-ng/2.1.6@user/channel#fac0999d78a3e7ab7c4cc96035a28931", force=True)
[options]
openssl/3.0.14*:no_fips=True
openssl/*:no_legacy=True
openssl/3.0.14*:use_validated_fips=True
openssl/*:with_zlibng=True
[replace_requires]
openssl/3.0.9 : openssl/3.0.9@user/channel#4faa23d318801e3887bc428ace1f8e4d
zlib-ng/* : zlib-ng/2.1.6@user/channel#fac0999d78a3e7ab7c4cc96035a28931
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 viaself.requires("openssl/3.2.1")
but we also need to package the FIPS module (i.e.fips.so
orfips.dll
orfips.dylib
) from the officially supported version, i.e.openssl/3.0.8
. See the official OpenSSL doc:My initial solution (that sorta works) was the following:
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 thehost
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?