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 [2] - https://github.com/openjdk/jdk/pull/15539 On Thu, Jul 13, 2023 at 1:01 PM Sean Mullan <sean.mul...@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 > >>>> > >>>> 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 > >>>>> > >>>>> (†) - 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 > >>>>>>> (†) - Thanks to @fferrari for his contributions to this proposal. > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > >