[External] : Re: RFD: Services lockdown for security providers

Anthony Scarpino anthony.scarpino at oracle.com
Tue Sep 19 20:42:00 UTC 2023


Hi Martin,

Thanks for the proposal. Your documents mostly describe the solution. 
Can you provide more of the motivations and use-cases for the change? 
Do you see non FIPS-140 applications using this feature?

The feature does provide a comprehensive filtering system for JCA. The 
syntax, while powerful, seems like it would be somewhat error-prone and 
hard to use. We are also concerned that using the filter requires the 
sysadmin or developer to know about the service and algorithm details of 
every provider and which is required and which is not, all of which is 
not easily determined.

thanks

Tony

On 9/1/23 9:30 AM, Martin Balao wrote:
> Hi Sean,
> 
> Thanks for clarifying your idea. I understand your motivation and share 
> your concerns. I can think of how this application-specific knowledge 
> can turn into a library-specific one in real scenarios, which may open 
> the door for undesired dependencies. I also agree with being wary about 
> doing stack walks in a Security Manager style at time of use. We have to 
> give it some thought. Just in case, we reserved the characters ":" and 
> "," in our proposal for the Security Providers Filter [1] [2]. Extending 
> the filter syntax in the future (in a backward compatible way) should 
> not be a problem.
> 
> Martin.-
> 
> --
> [1] - https://bugs.openjdk.org/browse/JDK-8315487 
> <https://bugs.openjdk.org/browse/JDK-8315487>
> [2] - https://github.com/openjdk/jdk/pull/15539 
> <https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/15539__;!!ACWV5N9M2RV99hQ!OvzI8vsHVWp9vomkrmCkv4IOarvy7REU3UpB1cPQFOBcB9D6RxtWkTYdZDZAVnKNKrlC0yYnY36MdEGkOnfa$>
> 
> 
> On Thu, Jul 13, 2023 at 1:01 PM Sean Mullan <sean.mullan at oracle.com 
> <mailto:sean.mullan at oracle.com>> wrote:
> 
> 
> 
>     On 7/13/23 12:27 PM, Martin Balao wrote:
>      > On 7/13/23 12:06, Sean Mullan wrote:
>      >> One other comment that I thought of - is that from a practical
>      >> standpoint, I think it will be hard to unilaterally disable an
>     algorithm
>      >> at the JCE layer unless it is so broken that almost no code ever
>     uses
>      >> it, say MD2 or RC2. There may be cases where a weak algorithm is
>      >> acceptable, for example using MD5 for a checksum. (For a real
>     example,
>      >> UUID.nameUUIDFromBytes uses MD5 to generate a UUID).
>      >>
>      >> If you have a single case in your application where a weak
>     algorithm is
>      >> ok to use, you won't be able to disable it across the board.
>      >
>      > Yes, I agree with this observation. In fact, our original
>     motivation was
>      > not to disable an algorithm across the board but a specific
>      > implementation of it —i.e. blocking the implementation from
>     provider X,
>      > because we want the one from provider Y or prefer the algorithm
>     not to
>      > be available. What we also have in mind is using this enhancement in
>      > combination with security profiles that can enforce policies of
>     allowed
>      > algorithms, at the risk of requiring changes in an application to be
>      > compliant.
>      >
>      >>
>      >> At the risk of complicating your syntax and implementation, it
>     may be
>      >> worth exploring adding the name of a class to the syntax for
>     cases like
>      >> this. But my comment is more about thinking about this a bit
>     more first.
>      >>
>      >> Or perhaps adding some extensibility into the format would be a good
>      >> idea in case we want to add something like this down the line.
>      >>
>      >
>      > I have a couple of questions regarding this idea:
>      >
>      > 1) Isn't the class name an implementation detail? My concern is
>     not much
>      > on how to extend the syntax but on binding the filter value to
>     internal
>      > names.
> 
>     It is an application-specific detail. I would expect this to be applied
>     by applications that are most familiar with their usage, and not as
>     part
>     of a global configuration.
> 
>      > 2) Why wouldn't a combination of Security Provider + Service Type +
>      > Algorithm be enough to identify a specific implementation?
> 
>     Because that doesn't tell you who is calling the specific
>     provider/service and whether that use case is acceptable or not. Also
>     most code that calls JCE APIs doesn't specify a specific provider.
> 
>     Again, I think this needs more thought, and I am not suggesting this is
>     the best course of action, but one thought is a syntax something
>     like this:
> 
>     jdk.security.providers.filter=java.util.UUID.nameUUIDFromBytes:MessageDigest.MD5;!*.MessageDigest.MD5;*
> 
>     But, that would probably mean extending the implementation to do a
>     stack
>     walk to check if the specified class was one of the callers, which I am
>     very wary about doing something like this. But the overall issue still
>     remains for me. Maybe we should not be providing a way to unilaterally
>     disable algorithms unless it can be used more effectively in practice.
>     Otherwise I don't like the idea of telling a user they have to
>     re-enable
>     the algorithm even if they only have a single case where it is
>     acceptable.
> 
>     --Sean
> 
>      > Thanks,
>      > Martin.-
>      >
>      >
>      >> --Sean
>      >>
>      >>
>      >> On 7/13/23 11:44 AM, Martin Balao wrote:
>      >>> Hi Sean,
>      >>>
>      >>> Thanks for your feedback.
>      >>>
>      >>> Just to give some visibility, we have implemented most of the
>      >>> functionality and are now working on final adjustments, more tests
>      >>> coverage, documentation and internal reviews. The implementation is
>      >>> pretty much aligned to what we previously discussed, with the
>     exception
>      >>> of algorithm's alias that turned up to have more complexity than
>      >>> anticipated —particularly in the legacy mode of registering
>     Services—.
>      >>>
>      >>> We will send a PR for public discussion in the coming weeks.
>      >>>
>      >>> Martin.-
>      >>>
>      >>>
>      >>> On 6/14/23 12:40, Sean Mullan wrote:
>      >>>> This proposal looks pretty good, although I think I would like
>     to see
>      >>>> more examples and a prototype if you have it.
>      >>>>
>      >>>> I think this would work well in conjunction with Sean Coffey's
>      >>>> enhancement to add a security category to the java
>     -XshowSettings option
>      >>>> [1]. This would help debug issues with the syntax. The provider
>      >>>> suboption could be enhanced (perhaps by default, perhaps with an
>      >>>> additional suboption) to show the services that are disabled,
>     ex, with
>      >>>> the property set to
>      >>>>
>      >>>> jdk.security.providers.filter=!*.MessageDigest.MD5;
>      >>>> !*.MessageDigest.MD2; *:
>      >>>>
>      >>>> it would show something like:
>      >>>>
>      >>>>            Provider name: SUN
>      >>>>            Provider information: ...
>      >>>>            Provider services: (type : algorithm)
>      >>>>                ...
>      >>>>                MessageDigest : MD2 (disabled)
>      >>>>                MessageDigest : MD5 (disabled)
>      >>>>                ...
>      >>>>
>      >>>> I would even add that as a debugging tip in the documenting of the
>      >>>> syntax.
>      >>>>
>      >>>> --Sean
>      >>>>
>      >>>> [1] https://github.com/openjdk/jdk/pull/14394
>     <https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/14394__;!!ACWV5N9M2RV99hQ!OvzI8vsHVWp9vomkrmCkv4IOarvy7REU3UpB1cPQFOBcB9D6RxtWkTYdZDZAVnKNKrlC0yYnY36MdHp89xAv$>
>      >>>>
>      >>>> On 5/24/23 5:03 PM, Martin Balao wrote:
>      >>>>> Hi,
>      >>>>>
>      >>>>> Thanks Anthony for your feedback.
>      >>>>>
>      >>>>> We've been exploring the syntax and semantics for this new
>     property
>      >>>>> further, with the goal of making it more consistent and
>     simple while
>      >>>>> retaining expressiveness power. We understand the importance
>     of clarity
>      >>>>> to minimize the risk of security providers, service types or
>     algorithms
>      >>>>> being unexpectedly enabled.
>      >>>>>
>      >>>>> In this new iteration of the proposal, we explore a filter
>     that has
>      >>>>> similarities to the serialization filter (jdk.serialFilter).
>     We think
>      >>>>> that it could be beneficial to leverage on a specification to
>     which the
>      >>>>> user is familiar already.
>      >>>>>
>      >>>>>
>      >>>>> General structure
>      >>>>> ====================
>      >>>>>
>      >>>>> jdk.security.providers.filter=pattern-1; pattern-2; ...;
>     pattern-n
>      >>>>>
>      >>>>> The property jdk.security.providers.filter is an overrideable
>     Security
>      >>>>> property. Thus, a System property with the same name exists
>     and, when
>      >>>>> specified, overrides any value in its Security counterpart.
>     When not
>      >>>>> specified (value is null), filtering capabilities are completely
>      >>>>> disabled: all installed security providers, service types and
>      >>>>> algorithms
>      >>>>> are allowed. If any of these properties are set during run
>     time, the
>      >>>>> filter could be initialized already and the new value may not
>     take
>      >>>>> effect.
>      >>>>>
>      >>>>> When filtering capabilities are enabled, each service is checked
>      >>>>> against
>      >>>>> the filter before registration. Notice that this affects both the
>      >>>>> initial list of security providers as well as those dynamically
>      >>>>> installed during run time. Once a service is registered,
>     instances
>      >>>>> of it
>      >>>>> can be obtained and used without any other checks that could
>     affect
>      >>>>> performance.
>      >>>>>
>      >>>>> The registration of a service involves a combination of a
>     security
>      >>>>> provider, service type and algorithm. Each combination is
>     evaluated
>      >>>>> against the filter patterns, from left to right. When a
>     pattern matches
>      >>>>> —or, in other words, the rule concerns the service to be
>     registered—, a
>      >>>>> decision is made: the service will be allowed or denied. When a
>      >>>>> decision
>      >>>>> is made, remaining patterns are not checked for the service under
>      >>>>> consideration. When all patterns are checked and a decision
>     is not
>      >>>>> made,
>      >>>>> the default behavior is to deny the service registration.
>      >>>>>
>      >>>>> Contrary to the serialization filter, white spaces between
>     patterns do
>      >>>>> not have any significance.
>      >>>>>
>      >>>>>
>      >>>>> Pattern matching
>      >>>>> =====================================================
>      >>>>>
>      >>>>> pattern := ! security-provider.service-type.algorithm
>      >>>>>
>      >>>>> pattern := security-provider.service-type.algorithm
>      >>>>>
>      >>>>> A canonical pattern consists of 3 hierarchical levels
>     separated by ".".
>      >>>>>     From left to right in lexicographic order, these levels
>     denote a
>      >>>>> security provider, a service type and an algorithm. If a
>     pattern starts
>      >>>>> with "!", the decision made upon matching is to deny the service
>      >>>>> registration. Otherwise, the service registration is allowed.
>     White
>      >>>>> spaces between "!" and the rest of the pattern do not have any
>      >>>>> significance.
>      >>>>>
>      >>>>> For a match to be successful, the security provider name, the
>     service
>      >>>>> type and the algorithm have to match the pattern exactly (case
>      >>>>> insensitive). If the service type of a security provider
>     interprets the
>      >>>>> algorithm as a transformation composed of different parts,
>     the full
>      >>>>> transformation has to be specified in the pattern: the filter
>     takes a
>      >>>>> conservative approach and does not make any assumptions of
>     what an
>      >>>>> algorithm name means. For example, "AES" as the algorithm of a
>      >>>>> canonical
>      >>>>> filter pattern will not match an "AES/ECB/PKCS5Padding"
>     transformation.
>      >>>>>
>      >>>>> If an algorithm alias is specified in the filter pattern, a
>     service
>      >>>>> registering the alias will be matched.
>      >>>>>
>      >>>>> For convenience, it's possible to specify patterns in
>     non-canonical
>      >>>>> forms:
>      >>>>>
>      >>>>> 1) At any level, the security provider, the service type or the
>      >>>>> algorithm name can contain wildcards ("*") to represent zero
>     or more
>      >>>>> repetitions of any character;
>      >>>>>
>      >>>>> 2) The .algorithm part can be omitted to imply all algorithms
>     under the
>      >>>>> security provider and service type;
>      >>>>>
>      >>>>> 3) The .service-type.algorithm part can be omitted to imply
>     all service
>      >>>>> types and algorithms under the security provider; and,
>      >>>>>
>      >>>>> 4) The non-canonical form #1 can be combined with either #2
>     or #3.
>      >>>>>
>      >>>>>
>      >>>>> Security provider, service type and algorithm names escaping
>      >>>>> =================================================================
>      >>>>>
>      >>>>> If the security provider, service type or algorithm name contains
>      >>>>> any of
>      >>>>> the characters "\", ".", ";" or "*", they have to be escaped by
>      >>>>> prepending the character "\". If the character "\" is found not
>      >>>>> escaping
>      >>>>> a character, it's silently discarded.
>      >>>>>
>      >>>>> White spaces are discarded at the beginning and end of names.
>      >>>>>
>      >>>>> It's worth mentioning that the described escaping rules apply
>     to the
>      >>>>> jdk.security.providers.filter property value as read in
>      >>>>> java.lang.System::getProperty or
>     java.security.Security::getProperty.
>      >>>>> Additional escaping might be needed depending on how the
>     property is
>      >>>>> passed. For example, Security properties require "\"
>     characters to be
>      >>>>> escaped. Thus, to match a provider name whose name is "\.", a
>     filter
>      >>>>> would require the "jdk.security.providers.filter=\\\\\\."
>     entry in the
>      >>>>> java.security file. See more about this in
>     java.util.Properties::load
>      >>>>> [1].
>      >>>>>
>      >>>>>
>      >>>>> Examples (correct)
>      >>>>> ====================
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable all security providers, service types and algorithms:
>      >>>>>
>      >>>>> jdk.security.providers.filter=
>      >>>>>
>      >>>>> or
>      >>>>>
>      >>>>> jdk.security.providers.filter=*
>      >>>>>
>      >>>>> or
>      >>>>>
>      >>>>> jdk.security.providers.filter=*.*
>      >>>>>
>      >>>>> or
>      >>>>>
>      >>>>> jdk.security.providers.filter=*.*.*
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable everything except for the MD5 algorithm in MessageDigest
>      >>>>> services
>      >>>>> when implemented by the SUN security provider:
>      >>>>>
>      >>>>> jdk.security.providers.filter=!SUN.MessageDigest.MD5; *
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable everything except for the MD5 algorithm in MessageDigest
>      >>>>> services, irrespective of the security provider:
>      >>>>>
>      >>>>> jdk.security.providers.filter=!*.MessageDigest.MD5; *
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable everything except for algorithms using MD5,
>     irrespective of the
>      >>>>> security provider and the service type:
>      >>>>>
>      >>>>> jdk.security.providers.filter=!*.*.*MD5*; *
>      >>>>>
>      >>>>> Notice that in this case there are wildcards at the beginning and
>      >>>>> end of
>      >>>>> the algorithm name. The reason is to match MD5 uses in
>     algorithms such
>      >>>>> as HmacMD5, MD5withRSA, PBEWithMD5AndDES, etc.
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable everything except for the RC4 algorithm in Cipher
>     services when
>      >>>>> implemented by the SunJCE security provider:
>      >>>>>
>      >>>>> jdk.security.providers.filter=!SunJCE.Cipher.ARCFOUR; *
>      >>>>>
>      >>>>> or
>      >>>>>
>      >>>>> jdk.security.providers.filter=!SunJCE.Cipher.RC4; *
>      >>>>>
>      >>>>> or
>      >>>>>
>      >>>>>
>     jdk.security.providers.filter=!SunJCE.Cipher.1\.2\.840\.113549\.3\.4; *
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable the SUN security provider only, with all its service
>     types and
>      >>>>> algorithms. Other security providers must be disabled.
>      >>>>>
>      >>>>> jdk.security.providers.filter=SUN
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable the SUN security provider only, with all its service
>     types and
>      >>>>> algorithms except for MessageDigest. Other security providers
>     must be
>      >>>>> disabled.
>      >>>>>
>      >>>>> jdk.security.providers.filter=!SUN.MessageDigest; SUN
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>>
>      >>>>> Examples (mistakes)
>      >>>>> ====================
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable everything except for the MD5 algorithm, irrespective
>     of the
>      >>>>> security provider and the service type:
>      >>>>>
>      >>>>> jdk.security.providers.filter=*; !*.*.MD5
>      >>>>>
>      >>>>> This is wrong because the pattern "*" is matched first and a
>     decision
>      >>>>> allowing MD5 will be made immediately after. The pattern
>     "!*.*.MD5"
>      >>>>> will
>      >>>>> never be checked.
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable all SUN service types except for MessageDigest.
>     Disable other
>      >>>>> security providers.
>      >>>>>
>      >>>>> jdk.security.providers.filter=!SUN.MessageDigest
>      >>>>>
>      >>>>> While non-SUN security providers are effectively disabled,
>     this is
>      >>>>> wrong
>      >>>>> because SUN services other than MessageDigest will not match any
>      >>>>> pattern
>      >>>>> and, by default, the decision is to deny registration.
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>> Enable the SunPKCS11 security provider only.
>      >>>>>
>      >>>>> jdk.security.providers.filter=SunPKCS11
>      >>>>>
>      >>>>> This is wrong because the SunPKCS11 provider has to be
>     identified by
>      >>>>> its
>      >>>>> name instead of its class. A possible name would have the form of
>      >>>>> SunPKCS11-NAME. In a filter, this can be matched either by
>      >>>>> "SunPKCS11-NAME" or "SunPKCS11-*".
>      >>>>>
>      >>>>> --
>      >>>>>
>      >>>>>
>      >>>>> Look forward to your thoughts.
>      >>>>>
>      >>>>> Thanks.-
>      >>>>>
>      >>>>>
>      >>>>> --
>      >>>>> [1] -
>      >>>>>
>     https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Properties.html#load%28java.io.Reader%29 <https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Properties.html#load%28java.io.Reader%29>
>      >>>>>
>      >>>>> (†) - Thanks to Francisco Ferrari (@fferrari) for his
>     contributions to
>      >>>>> this proposal.
>      >>>>>
>      >>>>>
>      >>>>>
>      >>>>>
>      >>>>> On 2/24/23 14:49, Anthony Scarpino wrote:
>      >>>>>> Hi Martin,
>      >>>>>>
>      >>>>>> Interesting proposal.  I think Alternative 1 is a better
>     direction to
>      >>>>>> explore from a code structure standpoint.  If I remember
>     correctly,
>      >>>>>> Preferred Provider is accessed when getting a service or
>     instance
>      >>>>>> of the
>      >>>>>> algorithm.  That happens on a per-operation basis.  What you
>      >>>>>> describe is
>      >>>>>> something that would reshape contents of the ProviderList where
>      >>>>>> algorithms or services would not be in the list at all.  That is
>      >>>>>> were I
>      >>>>>> think #2 gets too complex in trying to handle both in the same
>      >>>>>> property.
>      >>>>>>      #2 may end up putting all checks in a per-operation check,
>      >>>>>> hindering
>      >>>>>> performance every time as the list grows.
>      >>>>>>
>      >>>>>> I agree this is mostly used in the FIPS situation or where
>     someone
>      >>>>>> wants
>      >>>>>> to disable an algorithm completely, say MD5.  In those cases
>     it's best
>      >>>>>> to just prevent the algorithm from ever being available.
>      >>>>>>
>      >>>>>> On the smaller details side that you list.  I think the name
>      >>>>>> ".enabled"
>      >>>>>> doesn't fit, particularly as the first thing in the example
>      >>>>>> disables all
>      >>>>>> Ciphers :).  I don't have any suggestions at this time.
>      >>>>>>
>      >>>>>> As far as the syntax.  I think it maybe a bit difficult to
>     parse in
>      >>>>>> code
>      >>>>>> and mental to disable all Ciphers, then enable just for
>     SunJCE and
>      >>>>>> SUN.
>      >>>>>> The SUN '*" confused me until I realized you were enabling
>     Ciphers.
>      >>>>>> Seems too easy to get wrong.  I know you weren't making a
>     formal spec,
>      >>>>>> but we have to start somewhere.
>      >>>>>>
>      >>>>>> thanks
>      >>>>>>
>      >>>>>> Tony
>      >>>>>>
>      >>>>>>
>      >>>>>> On 2/17/23 10: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 <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