RFD: Services lockdown for security providers
Peter Firmstone
peter.firmstone at zeus.net.au
Wed May 24 22:48:43 UTC 2023
These are examples of how we currently lock down the JVM, to limit
providers, policy files are generated using a tool, it may do as an
interim control measure, until something else is provided, it is of
course a deprecated feature, subject to future removal, but it may do
the job temporarily, without introducing code dependencies.
https://github.com/pfirmstone/JGDMS/blob/14608ea34eb7c109d41e296a62669522862f6a49/qa/harness/policy/defaultsecuretest.policy#LL194C27-L194C27
https://github.com/pfirmstone/JGDMS/blob/14608ea34eb7c109d41e296a62669522862f6a49/qa/harness/policy/defaultsecuretest.policy#L621
https://github.com/pfirmstone/JGDMS/blob/14608ea34eb7c109d41e296a62669522862f6a49/qa/harness/policy/defaultsecuretest.policy#L644
https://github.com/pfirmstone/JGDMS/blob/14608ea34eb7c109d41e296a62669522862f6a49/qa/harness/policy/defaultsecuretest.policy#L688
--
Regards,
Peter.
On 18/02/2023 4:52 am, Martin Balao wrote:
> Hi,
>
> We would like to discuss a limitation in the current configuration
> capabilities for security providers and possible solutions that we are
> exploring (†).
>
> As you know, current configuration capabilities in java.security allow
> users to install security providers, decide their priority in a list
> (security.provider.<n> properties) and even circumvent this priority
> for specific algorithms (jdk.security.provider.preferred property).
> However, there is no granularity in terms of what service types and
> algorithms are enabled once a security provider is installed: it's an
> all or nothing scheme. It is worth noting that security providers can
> bring with them a diverse range of service types. As an example, the
> SUN security provider comes with the following service types:
> SecureRandom, Signature, KeyPairGenerator,
> AlgorithmParameterGenerator, AlgorithmParameters, KeyFactory,
> MessageDigest, CertificateFactory, KeyStore, CertStore, Policy,
> Configuration, CertPathBuilder and CertPathValidator [1].
>
> In some cases, the user may need to enforce that all cryptographic
> primitives come from a specific security provider. This could happen,
> for example, when operating in a FIPS-compliant environment or under
> strict security policies. To better illustrate, let's say that the
> user requires that all cryptographic operations are performed in a
> Hardware Security Module (HSM). On the OpenJDK side, this means that
> the implementation for Cipher, Signature, Mac and other cryptographic
> services must be the one in the SunPKCS11 security provider. Let's
> also suppose that other non-cryptographic services such as those for
> certificates validation and TLS are required, and their implementation
> is in the SUN and SunJSSE security providers respectively. Setting
> SunPKCS11 at the highest priority of the list is not a strong
> guarantee to ensure that all cryptographic operations come from it:
> it's possible that an algorithm for Signature is not implemented in
> SunPKCS11 or in its underlying token but in the SUN security provider.
> Disabling the SUN security provider wouldn't be an option in this case
> because we need its certificates validation service.
>
> This problem goes beyond OpenJDK default security providers. Even if
> we come up with a new layout for service types, algorithms and
> providers —putting backward compatibility issues aside—, there is
> always the possibility that a 3rd party security provider does not
> follow any services grouping convention. It might also be the case
> that we need to disable a specific algorithm only —i.e. for
> cryptographic policy reasons— and TLS or JAR signing properties fall
> short.
>
> In our view, it would be beneficial to add more configuration
> flexibility and control to the existing API in which any security
> provider can be plugged in, in the form of deciding which service
> types and algorithms are enabled for each installed provider.
>
> There are 2 alternatives that we are exploring to tackle this problem.
>
> Alternative #1
> ===========================
>
> Introduce a new security property to decide which service types and
> algorithms are enabled for each security provider. The default value
> for this property would be empty, which keeps this feature disabled
> and all services from installed security providers available.
>
> As for the new property's syntax and semantics, we've been considering
> an allow-list along the lines of:
>
> jdk.security.provider.enabled = security-provider-1 { service-type-1 :
> alg-1, ... ; ... } , ...
>
> Note: we need a formal syntax specification, this is for illustration
> only.
>
> As part of the syntax we are considering the use of wildcards (*) to
> match multiple security providers, service types and algorithms, and
> minus signs (-) to remove service types. When a service type is
> removed, the action applies to all algorithms and any attempt to
> specify them explicitly would be an error. The minus sign cannot be
> used at the algorithm level. We are also thinking that in case of a
> partial or total contradiction between conditions, the right-most
> value applies on top of the others. If a security provider, service
> type or algorithm does not exist, we can simply write a debug warning
> and ignore it. As for the name of the algorithms, we can also include
> Ciphers transformations.
>
> Example:
>
> jdk.security.provider.enabled = * { -Cipher }, SunJCE { Cipher :
> AES/GCM/NoPadding, DES ; Signature }, SUN { * ; -Signature }
>
> This would be interpreted as:
>
> * Irrespective of the provider (*), Cipher services should be removed
> (-). This rule would be superfluous in this case because the property
> itself is an allow-list and there is nothing to the left that enables
> Cipher service types for any provider.
> * From the SunJCE security provider, Cipher services with
> AES/GCM/NoPadding and DES transformations are allowed, and Signature
> services with any algorithm are allowed. Notice that there is a
> shortcut here: the algorithm list that follows the service name, "':
> alg-1, ..." is optional. When omitted all the service's algorithms are
> enabled.
> * From the SUN security provider, every service type is allowed
> except Signature (recall that a minus sign can only apply to a
> service, removing all associated algorithms).
>
> It's not the goal of this proposal to invalidate property values that
> lead to inconsistent internal states, such as "the Cipher service of
> SunJCE depends on AlgorithmParameters from SUN". This is because the
> combinations for a check are virtually infinite: there can be 3rd
> party security providers with their own semantics and dependencies. In
> the same way, we cannot determine at start time any application
> dependencies. It's up to the user to analyze all types of dependencies
> before setting a value.
>
>
> Alternative #2
> ===========================
>
> Introduce a boolean security property to turn the value of the
> existing jdk.security.provider.preferred property into the only
> combinations of algorithm, service and provider that are allowed:
>
> jdk.security.provider.preferredOnly = true
>
> The default value for the new property would be "false", keeping the
> current "preferred" behavior in which all algorithms and services from
> installed security providers are available.
>
> Contrary to Alternative #1, the user has to explicitly list the
> algorithms and cannot rely on wildcards to express wide categories
> such as "all Cipher algorithms from SunJCE" or "all algorithms from
> SunJCE". The use of minus signs to remove service types or algorithms
> wouldn't be available either.
>
> In order to mitigate the burden on users we can consider extending
> jdk.security.provider.preferred syntax as long as we keep
> backward-compatibility and stay within the boundaries of a "preferred"
> semantics. For example, we can accept a value of
> "jdk.security.provider.preferred=SunJCE" to mean that any service and
> any algorithm from SunJCE is either preferred or allowed, depending on
> the value of jdk.security.provider.preferredOnly. This case would be a
> service type and algorithm wildcard. We can also define an
> algorithms-only wildcard, such as Cipher.*:SunJCE.
>
> Alternative #2 has the advantage of reusing most or all of the
> existing syntax. However, it's worth noticing that it implies an
> overloaded semantic that can turn confusing or inconvenient in some
> cases. As an example, a user that relies on the prioritized security
> providers list for most of the algorithms and has only a few preferred
> exceptions, would need to express preferences by extension upon
> turning on this feature. Alternative #1 keeps preferences and
> availability as two separate concepts, in a more clear way.
>
>
> Thanks,
> Martin.-
>
> --
> [1] -
> https://docs.oracle.com/en/java/javase/17/security/oracle-providers.html#GUID-3A80CC46-91E1-4E47-AC51-CB7B782CEA7D
> (†) - Thanks to @fferrari for his contributions to this proposal.
>
More information about the security-dev
mailing list