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

Load root certificates at image build time #1999

Closed
christianwimmer opened this issue Dec 16, 2019 · 17 comments
Closed

Load root certificates at image build time #1999

christianwimmer opened this issue Dec 16, 2019 · 17 comments
Assignees

Comments

@christianwimmer
Copy link

The JDK ships a file with root certificates: lib/security/cacerts. The JDK TrustStoreManager is responsible for loading. If no system property is set explicitly, then the cacerts file of the JDK is loaded. But that can be overridden using system properties.

We have a few options how to handle that in a native image:

  1. Do not embed any root certificates into a native image. That means that the application needs to be shipped with a cacerts file, or the system properties must be used to locate certificates already installed on the system. I think that is a bad option though because it is difficult for users, and no certificates are available out-of-the-box without additional configuration.
  2. Embed the root certificates into the native image, but still at run time look at the system properties and allow certificates from an alternative location to be loaded.
  3. Embed the root certificates into the native image, and do not allow any different certificates to be loaded at run time.

The difference between option 2) and 3) from a security and usability perspective: In option 2) we treat security as something that can be configured at image run time. In option 3), we consider security as something that is fixed at image build time and therefore cannot be modified (explicitly or accidentally) at run time.

We believe that "immutable security" is a valuable feature of Native Image and therefore implement solution 3)

@christianwimmer christianwimmer self-assigned this Dec 16, 2019
@dmlloyd
Copy link
Contributor

dmlloyd commented Dec 17, 2019

I would prefer solution "1" or "2", if anything. I'm not sure that "immutable security" is a feature per se; it's more of a consequence.

@sberyozkin
Copy link

@christianwimmer It is not clear if 3) allows for the custom certificates be included at the build time ?

Option 2) looks the best though, can you please clarify why 3) is preferred to letting the native image users customize the default certificates at run time ?

@christianwimmer
Copy link
Author

@sberyozkin Yes, custom certificates can be included at image build time. All system properties such as javax.net.ssl.trustStore can be specified at image buid time.

@dmlloyd "immutable security" is a guiding principle of Native Image. For example, not allowing dynamic class loading at run time makes the code immutable at run time, allowing to reason about security at image build time. Do you have any technical arguments or use cases why solution 3) would not work?

@dmlloyd
Copy link
Contributor

dmlloyd commented Dec 17, 2019

@dmlloyd "immutable security" is a guiding principle of Native Image. For example, not allowing dynamic class loading at run time makes the code immutable at run time, allowing to reason about security at image build time. Do you have any technical arguments or use cases why solution 3) would not work?

No, I think it will work, but I suspect we'll end up having to add a Quarkus workaround to allow the trust store to be rebuilt from cacerts at run time, which is not ideal.

@sberyozkin
Copy link

sberyozkin commented Dec 17, 2019

@christianwimmer, thanks...

Do you have any technical arguments or use cases (for 2))

The native image HTTP client target URI varies per deployment thus making it difficult to anticipate which certificates have to be included at the build time.

@christianwimmer
Copy link
Author

But we are only talking about the root certificates here. So do you have an actual use case where you right now set the javax.net.ssl.trustStore property for a Java VM to a certificate store that you do not have available at image build time?

@dmlloyd
Copy link
Contributor

dmlloyd commented Dec 18, 2019

I guess that depends on the length of time one expects a native image to be in use for. If you expect the image to be rebuilt every few weeks or even months, it's probably okay. Longer than that, it may become a problem at some point.

graalvmbot pushed a commit that referenced this issue Jan 18, 2020
@fcurts
Copy link

fcurts commented Feb 20, 2020

Option 3 rules out the use of binary distributions of third-party applications that don't contain the root certificates you need. (Based on my experience, it's not uncommon for corporations to have their own root certificates for internal use.) Hence option 2 seems more desirable to me, even though I'd generally want to set the alternative location(s) at build time (to the trust store of the target OS). This is also how standard tools such as curl work.

@fcurts
Copy link

fcurts commented May 18, 2020

@christianwimmer @dmlloyd Any more thoughts on this? I'm concerned that option 3 rules out the use of native-image for many use cases (including mine). I'm writing a CLI based tool that needs to fetch data over the network. In corporate environments this often requires internal certificates, which are typically available from the OS trust store. It doesn't seem reasonable to ask each of my users to build my tool on their own and add their certificates at build time.

To summarize my point, option 3 may be good enough for services, but isn't good enough for tools.

@zeeZ
Copy link

zeeZ commented Jul 10, 2020

Saw this "immutable security" thing mentioned in quarkusio/quarkus/issues/9713

Option 3 makes it very hard to build and test a single native image and use it in multiple environments with their own internal CA.

You're forced to either include and trust all CA from all environments at build time (why should an image run in production trust a certificate signed by the test environment CA?) or rebuild the image for each environment (no more build once, deploy anywhere). Testing in a dynamic environment where the CA is not known at build time becomes impossible.

IMHO a truststore is closer to application configuration than it is to application logic, and 3) is a step too far.

@collinpeters
Copy link

Does option 3 as a default for Graal actually preclude the ability for someone to use option 2 in their own binary? i.e. can I not just provide an option to my binary which will load additional trusted stores? I haven't spent much time Googling around for a good example, but this post on SO implies that if you haven't instantiated any SSL connections you can do System.setProperty( "javax.net.ssl.trustStore", "/usr/local/comp.jks" ); and set your own trust store.

@ntrp
Copy link

ntrp commented Aug 29, 2020

I would really like to avoid shipping client certificates with my application, we are currently fetching certificates at runtime

@christianwimmer
Copy link
Author

It is certainly possible to implement "option 2" as well. If anyone is willing to implement it, I'm happy to give the right directions. I don't know when we have resources available to address it, there are many other compatibility issues open that are have higher priority right now.

@jaikiran
Copy link
Contributor

jaikiran commented Sep 6, 2020

It is certainly possible to implement "option 2" as well.

Hello @christianwimmer,

Given that there is interest in supporting this use case, I've opened a PR #2831 with the potential changes to support this. The PR has the necessary details about the change.

@vsevel
Copy link

vsevel commented Oct 27, 2020

hello, here are my thought about it
https://groups.google.com/g/quarkus-dev/c/xS87YeiQd_o/m/gAar2LH9BgAJ

I really hope #2831 from @jaikiran will go through

@teshull
Copy link
Member

teshull commented Aug 6, 2021

Hello. Drawing from #2831 and #3091, I made a new PR with support for setting a certificate file for the default keystore at runtime: #3652. The description is in https://github.com/oracle/graal/blob/github/tshull/GR-32212_truststoremanager/docs/reference-manual/native-image/CertificateManagement.md

While the runtime behavior is more limited than JVM w.r.t. fallback support when invalid SystemProperties are present, I think what I added should be sufficient for realistic use cases.

Please let me know what you think.

@teshull
Copy link
Member

teshull commented Aug 30, 2021

Merged in e98ae39

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests