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