Date   

Re: LDAP Annotation and Database Hashing Proposal

Arjan Tijms
 

Hi,

On Thursday, July 20, 2017, Will Hopkins <will.hopkins@...> wrote:


On 07/20/2017 10:54 AM, Arjan Tijms wrote:
On Thu, Jul 20, 2017 at 07:18 am, Will Hopkins wrote:
First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.
Ok, good! :)



Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time.
It depends, many applications actually do decide those things and in those applications it are the developers as well who decide this.

In the simplest example, if I'm programming a micro application for IoT (on Raspberry pi) I'm the only developer and my application uses only one LDAP URL.

In a bigger example, when you build and operate your own website (like I did with zeef.com), you only have a select few different LDAP URLs, which are all configured up front in the application, and via a stage parameter (i.e. -Dstage=dev) the right one is chosen. Also there, when you do devops, essentially the developer choose all parameters and set all URLs and what have you.

This is actually rather common and an area where Java EE has traditionally been lacking, causing a small exodus to other platforms.
Sure, and we can easily support those use cases. But we should also support the use cases, which do still exist, of enterprise developers, or developers building an app that will be deployed in multiple heterogeneous environments. Why limit ourselves to just one use case?

Oh, that's definitely not what I'm advocating ;)

Especially in the beginning of the JSR I strongly advocated to support *both* options, and to support those as transparently as possible. There were some voices back then that seemed to argue for application defined configuration only, of which I'm definitely not a fan either.

 


Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.
That option should be taken into account, but as many (web) applications are developed in house and operated by the same company or group that develops it, we have to be careful not to think that deploying the application elsewhere to an unknown site and operated by a separate ops team is the only (or even the most common) use case.
Sure.

Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. 
Indeed, and the generic key/value map enables that.
To a point, but it specifying parameters implies that those parameters are rigid. Leaving it up the the impl allows a single instance of the impl to be flexible and handle a variety of situations.

I'm not sure I follow that...
 



In the current proposal it's:

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
   
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358",
        "PBKDF2.iterationCount=2048"
    }

A vendor can very easily and transparently extend that with extra parameters, e.g. :

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
    
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358", 
        "PBKDF2.iterationCount=2048"
        "com.oracle.webLogic.middleware.encryption.d2of2.tMinS=5"
    }

Where the extra parameter is used to set the minimal time the algorithm should take before returning.


but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.
As a developer myself and looking back at what my previous teams did, I'm 100% convinced developers do want that ;)
Perhaps, but I'm not sure that always leads to better security. If we make it so they don't have to care, and they know they'll get good security, they won't worry about parameters. 

I'm not entirely convinced about that. The issue is that this is largely what was said about security (mostly the proprietary identity store) being defined on the server, since it would, indeed, lead to better security.

However, as we know now, if developers can't configure every attribute there is, they simply avoid the offering altogether, which leads generally to far less secure applications.

If we don't give developers full and total control to all options here many will just code up their own database identity store, which I think is not quite what we want.


Your salt specification above, for example, is an anti-pattern. (Each password should have a different salt -- salt size is the value I'd argue we should support, if anything. If you want an algorithm that uses the same hash for every password, that's something you should have to write yourself.)

The above is just an example of course; the exact same parameter could either be defaulted, use a constant hash, or use a method reference of some kind.

What the default would be and what the expression exactly looks like was left open for now.

The key here is that developers are not required to set parameters, but can do so if needed.

Kind regards,
Arjan Tijms
 

Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).
This can still be done, since the parameters can be EL enabled and then fetch the config externally.

Similarly, parameters like the salt and iteration count can be defaulted. That way you can have 3 levels:

1. Specify only the class name; you get defaults for all parameters and it Just Works
2. Specify the parameters locally to match a specific DB or requirement
3. (via EL) fetch the parameter values externally

The most important rule should always be that the developer is in full control, or can be in full control. External overrides should be possible, but never be required. That is -the- big mistake that Java EE made in the past.
I agree, but I think we're only talking about what the mechanism for override is, and what the trade-off between simplicity and the override mechanism is. In practice, I don't think parameters are going to be very helpful to most developers. They can be used to tweak some simple things, but the simple things won't typically be necessary and the more complex things can't be handled by parameters.



P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).
You mean PBKDF2? That has already been implemented:

@ApplicationScoped
public class Pbkdf2HashAlgorithmImpl implements Pbkdf2HashAlgorithm {
 
    @Override
    public boolean verifyHash(char[] password, String hashedPassword, Map<String, String> parameters) {
        return 
            pbkdf2(
                password, 
                parameters.get("PBKDF2.salt").getBytes(),
                Integer.valueOf(parameters.get("PBKDF2.iterationCount"))
            )
            .equals(hashedPassword);
    }
    
    private String pbkdf2(char[] password, byte[] salt, int iterationCount) {
        try {
            return 
                Base64.getEncoder()
                      .encodeToString(
                          SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                                          .generateSecret(
                                             new PBEKeySpec(password, salt, iterationCount, 64 * 8))
                                          .getEncoded());
            
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new IllegalStateException(e);
        }
    }
    
}

See:

https://github.com/arjantijms/soteria/blob/expression-language/impl/src/main/java/org/glassfish/soteria/identitystores/hash/Pbkdf2HashAlgorithmImpl.java

The API is in javax.security.enterprise.identitystore.Pbkdf2HashAlgorithm combined with a description of the parameters it accepts ("BKDF2.salt" and "PBKDF2.iterationCount"

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


 


 


Re: WARNING! PLEASE READ! (Was: Fwd: Re: [javaee-security-spec] Moving to Java EE Github?)

Guillermo González de Agüero
 

Ok from me

On Thu, Jul 20, 2017 at 8:39 PM, Will Hopkins <will.hopkins@...> wrote:
So is everybody OK with me moving repos today?

SPEAK NOW OR FOREVER HOLD YOUR PEACE!


On 07/20/2017 10:38 AM, Will Hopkins wrote:
I thought I sent this out yesterday, but forgot to copy the list -- just as well that I wasn't able to complete the migration last night, although I did get started on the security-spec repo.

Please note the part about issue management -- I think it will be helpful to use issues to track what we're working on, to avoid duplicate effort or working at cross purposes -- for now, lets use soteria repo issues to track who's working on tasks.

Will

On 07/19/2017 12:49 PM, Will Hopkins wrote:
MOVING THE REPOS TODAY!

Unless there are objections, I plan to migrate the security-spec, security-api, and soteria repos to the Java EE github organization today. Since most of you are in Europe, I'll do it during the evening my time, which will be very late at night CET.

Before doing so, I'll disable access for everyone, to avoid interrupting a commit or an issue update. Once everything is successfully migrated, I'll re-enable access on the Java EE side.

ISSUE MANAGEMENT:

On a slightly different topic, I plan to triage the outstanding Issues for both security-spec (@javaee org) and soteria, and use them to manage the remaining work. Please plan to track work you're doing with github issues. I'll send a more detailed email on this topic soon.

Regards,

Will


-------- Forwarded Message --------
Subject: Re: [javaee-security-spec] Moving to Java EE Github?
Date: Tue, 18 Jul 2017 22:13:12 -0400
From: Will Hopkins <will.hopkins@...>
To: javaee-security-spec@javaee.groups.io


I think I'm about ready to migrate the repos to the javaee organization.

If anyone has work in flight that will be disrupted, please let me know. Otherwise, I'll plan to do the migration sometime tomorrow (Wednesday, 7/19).

The plan is to migrate as follows:
  • security-spec -> javaee/security-spec
    • issues are already there (migrated from java.net)
    • migrate the source only, using git clone
    • recreate releases based on migrated tags at the destination
    • will lose pull-request history, but should preserve everything else we need.
git clone --bare $GITHUB_URL_OLD_REPO
cd <repo-name>.git
git push --mirror $GITHUB_URL_NEW_REPO
  • security-api -> javaee/security-api
    • use github "transfer" function to migrate entire repo
  • soteria -> javaee/security-ri-soteria
    • use github "transfer function to migrate  entire repo
    • rename repo when transfer completes

I'll make a full (bare) clone of each repo before transferring it.

Seem like a reasonable plan?

Will




On 07/11/2017 02:21 PM, Werner Keil wrote:
Ok, let us know, if you need any help by those who have the necessary rights.

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Re: WARNING! PLEASE READ! (Was: Fwd: Re: [javaee-security-spec] Moving to Java EE Github?)

Will Hopkins
 

So is everybody OK with me moving repos today?

SPEAK NOW OR FOREVER HOLD YOUR PEACE!

On 07/20/2017 10:38 AM, Will Hopkins wrote:
I thought I sent this out yesterday, but forgot to copy the list -- just as well that I wasn't able to complete the migration last night, although I did get started on the security-spec repo.

Please note the part about issue management -- I think it will be helpful to use issues to track what we're working on, to avoid duplicate effort or working at cross purposes -- for now, lets use soteria repo issues to track who's working on tasks.

Will

On 07/19/2017 12:49 PM, Will Hopkins wrote:
MOVING THE REPOS TODAY!

Unless there are objections, I plan to migrate the security-spec, security-api, and soteria repos to the Java EE github organization today. Since most of you are in Europe, I'll do it during the evening my time, which will be very late at night CET.

Before doing so, I'll disable access for everyone, to avoid interrupting a commit or an issue update. Once everything is successfully migrated, I'll re-enable access on the Java EE side.

ISSUE MANAGEMENT:

On a slightly different topic, I plan to triage the outstanding Issues for both security-spec (@javaee org) and soteria, and use them to manage the remaining work. Please plan to track work you're doing with github issues. I'll send a more detailed email on this topic soon.

Regards,

Will


-------- Forwarded Message --------
Subject: Re: [javaee-security-spec] Moving to Java EE Github?
Date: Tue, 18 Jul 2017 22:13:12 -0400
From: Will Hopkins <will.hopkins@...>
To: javaee-security-spec@javaee.groups.io


I think I'm about ready to migrate the repos to the javaee organization.

If anyone has work in flight that will be disrupted, please let me know. Otherwise, I'll plan to do the migration sometime tomorrow (Wednesday, 7/19).

The plan is to migrate as follows:
  • security-spec -> javaee/security-spec
    • issues are already there (migrated from java.net)
    • migrate the source only, using git clone
    • recreate releases based on migrated tags at the destination
    • will lose pull-request history, but should preserve everything else we need.
git clone --bare $GITHUB_URL_OLD_REPO
cd <repo-name>.git
git push --mirror $GITHUB_URL_NEW_REPO
  • security-api -> javaee/security-api
    • use github "transfer" function to migrate entire repo
  • soteria -> javaee/security-ri-soteria
    • use github "transfer function to migrate  entire repo
    • rename repo when transfer completes

I'll make a full (bare) clone of each repo before transferring it.

Seem like a reasonable plan?

Will




On 07/11/2017 02:21 PM, Werner Keil wrote:
Ok, let us know, if you need any help by those who have the necessary rights.

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 



On 07/20/2017 12:38 PM, Guillermo González de Agüero wrote:


Similarly, parameters like the salt and iteration count can be defaulted. That way you can have 3 levels:

1. Specify only the class name; you get defaults for all parameters and it Just Works
2. Specify the parameters locally to match a specific DB or requirement
3. (via EL) fetch the parameter values externally

The most important rule should always be that the developer is in full control, or can be in full control. External overrides should be possible, but never be required. That is -the- big mistake that Java EE made in the past.
I agree, but I think we're only talking about what the mechanism for override is, and what the trade-off between simplicity and the override mechanism is. In practice, I don't think parameters are going to be very helpful to most developers. They can be used to tweak some simple things, but the simple things won't typically be necessary and the more complex things can't be handled by parameters.
 
Could you please provide an example of such a setting, please? Just to better understand. Otherwise, we could just wait for your new proposal to see.

Basically, it's the encoding of the hashed password. Parameters like salt, iterations, hash key size, etc. are all pretty standard. They can be dialed up or dialed down to make the hash stronger or weaker, and I think "stronger vs. weaker" is the level at which most people think about them. I doubt many developers are concerned about specifying precisely a certain number of iterations for some reason, they just want iterations count to be high enough to be secure, without imposing excessive overhead or resource consumption, and security most often wins out vs. resource consumption these days. Most will be happy if they can turn up the volume with a single knob, they don't need bass and treble and balance knobs. Even better: if the default volume is about right, and if the volume automatically goes up when you're driving at higher speeds.

In contrast, the format of the encoded string is not standard in any way that I'm aware of. There are probably LDAP vendors that do things in a common way, but for any given database user store, either the format has already been decided, because there are existing user accounts, or the developer won't care as long as the default format is reasonable (assuming the DB schema allows enough space for the chosen encoding format.

I can't think of any good way to standardize parameters to describe how the hashed password is encoded for storage, and that's the hard part, the part that you really have to adapt to. It's not a big deal if you have to use 4000 iterations instead of 2000, but it's a big deal if you can't parse the encoded password. And since the encoding is completely arbitrary and non-standard, that's the real problem, and that's what will likely force people to do their own implementation of HashAlgorithm. That can't be specified as Properties.

We could probably come up with an interface for encoding/decoding the hashed value, or for describing the encoded value as a string and passing it as a property. But that's a lot to spec out, and we just don't have time for it. It's complicated by the fact that decoding a hash potentially yields all the parameters that were used to generate the hash, so there'd need to be a generalized interface for returning those in a standard way. Plus, in some databases, the encodings used will vary, as legacy hashes are replaced with stronger hashes/different encodings when people change their password.

It's hard to argue against supplying Properties. It's not difficult to implement, and it might be useful. But I'm trying to keep the interface as simple as possible -- in part to reduce the number of additional TCK tests that need to be written -- and I suspect the Properties will rarely be useful. Some people will want to use them, but for many the defaults will be good enough, and many of those with specific requirements will already be forced to write an implementation in order to deal with encoding issues.

Will
-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 



On 07/20/2017 12:36 PM, Guillermo González de Agüero wrote:


On Thu, Jul 20, 2017 at 4:18 PM, Will Hopkins <will.hopkins@...> wrote:
Catching up on a lot of discussion ...

First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.

I'm still not sold on the interface vs name approach. I personally still prefer the name idea, but with a specific pattern as discussed before, so users just need to know the algorithm name and the runtime will find the implementation. I still don't want to have a hard dependency on a vendor specific class. But on the other hand, I support Arjan's proposal for EL expression returning just the class, which then the implementation can instantiate via CDI lookup.

Sorry for the confusion I may have caused. Waiting for your counterproposal :)
Perhaps the consensus isn't as strong as I thought!

Actually, I'm starting to come around a bit. I still don't like all the compile time dependencies, especially since using EL circumvents any type checking that might otherwise have occurred. And I don't like that the namespace for algorithms is now basically the entire entire Java FQN namespace, instead of a flat namespace of strings with some naming conventions.

That said, I take the point that Arjan makes, that looking up objects in CDI using names is un-idiomatic and basically isn't done.

Could we, perhaps, generate synthetic type names on the fly, from string names? That's not much different than evaluating an EL expression that returns a type, in terms of the type checking that occurs. The problem is how to associate the synthetic type with the actual impl object ... maybe something with Proxy? Just thinking out loud ... ;)

 

Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time. Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.

Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. In fact, we might want to specify a standard "LocalDefault" algorithm, with behavior up to the vendor or site.

Third, "{Algorithm:interations:saltsize}base64(salt):base64(hash)" was never intended as a way to configure algorithm attributes; rather, it was meant to be a standardized storage format for hashed passwords -- one that allowed an implementation determine what parameters to use just by parsing the hashed password, so that an impl could use one set of parameters when generating new password hashes, but continue to be able to verify old passwords that may have been hashed with a different set of parameters. That allows passwords to be updated to stronger security as they are changed.

I actually don't think we should specify a way to configure algorithm parameters. If our goal is simplicity, what's more simple than specifying the name (or IF) of the algorithm you want, and leaving the details up to the algorithm implementation? The problem is that there are so many possible variations we can't specify them all. They will never be portable. If we have to support parameters, then Properties is definitely a good, flexible way to go, but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.

Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).

Thoughts?

Will

P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).



On 07/20/2017 07:33 AM, Arjan Tijms wrote:
Hi,

Okay, as a picture says more than a thousand words I'll prepare a PR for this proposal today or tomorrow.

Thx!

Kind regards,
Arjan Tijms

On Thu, Jul 20, 2017 at 1:28 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

I missed that proposal. Looks good and complete to me, thanks!

Regards,

Guillermo González de Agüero

El jue., 20 jul. 2017 a las 12:38, Arjan Tijms (<arjan.tijms@...>) escribió:
Hi,

On Thu, Jul 20, 2017 at 12:26 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

Yes, your proposal is inline with mine. EL support there would be just a method reference that returns a class.

Good ;)

 

This could be used along my idea of setting just the name of the algorithm and then the runtime checking via "some mechanism" like the proposed string pattern.

Indeed.

 

But aside from that, how do we solve the attribute/configuration problems?

What about my previous proposal where I mention the key/value array?

@DataSourceDefinition uses the same approach:

    /**
     *  Used to specify  Vendor specific properties and less commonly
     * used <code>DataSource</code> properties such as:
     * <p>
     * <ul>
     * <li>dataSourceName
     * <li>networkProtocol
     * <li>propertyCycle
     * <li>roleName
     * </ul>
     * <p>
     *  Properties are specified using the format:
     *  <i>propertyName=propertyValue</i>  with one property per array element.
     * <p>
     * If a DataSource property is specified in the properties
     * element and the annotation element for the  property is also
     * specified, the annotation element value takes precedence.
     * @since 1.1
     */
    String[] properties() default {};


With that you can do:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}"
    hashAlgorithmParameters = { "salt=83689638687683", "iterations=2048" }
)

EL would be naturally supported as well:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}"
    hashAlgorithmParameters = { "salt=83689638687683", "iterations=2048", "#{someBean.myOtherParameters}" }
)

Where the expression can return a String or String[].


Kind regards,
Arjan Tijms




 
Maybe we could resuse Will's original proposal for the algorithm attribute, i.e.: {Algorithm:interations:saltsize}base64(salt):base64(hash)

In that case, when e.g. sha512:50:20base64:base64 is set, the runtime would lookup an "Application_HashAlgorithm_sha512" bean and when not found, a "Server_HashAlgorithm_sha512".

But the options would need to be passed in some way to the interface (maybe as a parameter?).

What do you think?


Regards,

Guillermo González de Agüero

El jue., 20 jul. 2017 a las 11:32, Arjan Tijms (<arjan.tijms@...>) escribió:
Hi,

On Thu, Jul 20, 2017 at 9:50 AM, Guillermo González de Agüero <z06.guillermo@...> wrote:

Applications would become non-portable everytime they need a different algorithm that the only one provided by the spec... or they will need to create a custom implementations, which is really not much better.


Okay, I understand what you mean here.

There's 2 classes (no pun) of provided classes; the ones in external jars that are included with the application, and the ones that the application server vendor provides.

The first case is like adding p:dataTable, the second indeed like persistence.xml for say generating a schema from classes.

The question is if hash algorithms can be sufficiently common wrt configuration that it even makes sense to have a single application support both org.glassfish.XYZAlgo offered by GlassFish and org.jboss.XYZAlgo on JBoss.

What I could think of is having an array of classes and first one available is used.

E.g.

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithm = {JBossSuperAlgorithm.class, GlassFishSuperAlgorithm.class}
)

But the compiler initially would need to have both classes on the compile class path (runtime they don't have to be there). So I don't think that's a good idea.

In this case the EL variant of that attribute may be better:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}" 
)


@Named
@ApplicationScoped
public class SomeBean {

    public Class<? extends HashAlgorithm> algorithm() {
        try {
            return Class.forName("org.jboss.super");
        } catch (...) {}

          try {
            return Class.forName("org.glassfish.super");
        } catch (...) {}

       // ...

    }

Thoughts?

Kind regards,
Arjan Tijms




-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: Packaging bundle vs jar

Will Hopkins
 

I use eclipse but not the maven plugin (just because I'm not familiar with it).

The symptom was that the jars did not jave OSGi info in them (or, indeed, a MANIFEST.MF file of any sort), so they couldn't be integrated with GF.

There may be other ways to fix it, but I was trying to do the simple thing to get it working, which was to restore the bundle packaging. The API jar currently uses bundle packaging as well, BTW.

There may also be another issue, possibly related to the changes to the snapshot repository. When I tried to do a release last night, everything worked (version numbers integrated, successful build/test, etc.), and it looked like it was uploading the binaries, but they never showed up in the staging repository. It shouldn't be necessary to specify the jvnet snapshot repo, since the jvnet-parent pom already declares it. I haven't had a chance to look at it any further.

Will

On 07/20/2017 01:02 PM, Arjan Tijms wrote:
Hi,

On Thursday, July 20, 2017, Will Hopkins <will.hopkins@...> wrote:
What we really need is the OSGi manifest information, but choosing "bundle" seemed like the easiest way to get that.

It had previously been set as "bundle", and the GF integration was working. Was there a reason for the change to "jar"?

The IDE (Eclipse) didn't seem to be quite happy with it. Wonder if the end result actually differs with either "bundle" or "jar". Both should produce a .jar with a META-INF/MANIFEST.MF.

Kind regards,
Arjan Tijms
 


On 07/20/2017 11:16 AM, Arjan Tijms wrote:
Hi,

I noticed this commit: https://github.com/javaee-security-spec/soteria/commit/421b6f001c31cd3d64bad0b0f62807ebbb1c7712

Where the comment said "bundle" is needed for GF integration. However JSF/Mojarra used "jar", and obviously has been integrated in GF as well.

The bundle (OSGi) information (MANIFEST.MF mostly) should be added to the jar, even without the maven project type being "bundle". 

Wondering what problems were exactly encountered, but I'm fairly sure packaging "bundle" should not be needed as I integrated Soteria into Payara without any issues.

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

 

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: Packaging bundle vs jar

Werner Keil
 

As an Eclipse Plugin/Bundle?

Especially JSR 363 and all relevant implementations plus extension modules are used by Eclipse projects like Smart Home without problems.
I know, some of these Maven plugins can be a little tricky, if the issues persist, I could ask Chris Senior to have a look, he helped us with OSGi metadata in those bundles and also uses them with major clients, so there everything works...

Werner


Re: Packaging bundle vs jar

Arjan Tijms
 

Hi,

On Thursday, July 20, 2017, Will Hopkins <will.hopkins@...> wrote:
What we really need is the OSGi manifest information, but choosing "bundle" seemed like the easiest way to get that.

It had previously been set as "bundle", and the GF integration was working. Was there a reason for the change to "jar"?

The IDE (Eclipse) didn't seem to be quite happy with it. Wonder if the end result actually differs with either "bundle" or "jar". Both should produce a .jar with a META-INF/MANIFEST.MF.

Kind regards,
Arjan Tijms
 


On 07/20/2017 11:16 AM, Arjan Tijms wrote:
Hi,

I noticed this commit: https://github.com/javaee-security-spec/soteria/commit/421b6f001c31cd3d64bad0b0f62807ebbb1c7712

Where the comment said "bundle" is needed for GF integration. However JSF/Mojarra used "jar", and obviously has been integrated in GF as well.

The bundle (OSGi) information (MANIFEST.MF mostly) should be added to the jar, even without the maven project type being "bundle". 

Wondering what problems were exactly encountered, but I'm fairly sure packaging "bundle" should not be needed as I integrated Soteria into Payara without any issues.

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

 


Re: LDAP Annotation and Database Hashing Proposal

Guillermo González de Agüero
 

Hi,

On Thu, Jul 20, 2017 at 5:31 PM, Will Hopkins <will.hopkins@...> wrote:


On 07/20/2017 10:54 AM, Arjan Tijms wrote:
On Thu, Jul 20, 2017 at 07:18 am, Will Hopkins wrote:
First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.
Ok, good! :)



Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time.
It depends, many applications actually do decide those things and in those applications it are the developers as well who decide this.

In the simplest example, if I'm programming a micro application for IoT (on Raspberry pi) I'm the only developer and my application uses only one LDAP URL.

In a bigger example, when you build and operate your own website (like I did with zeef.com), you only have a select few different LDAP URLs, which are all configured up front in the application, and via a stage parameter (i.e. -Dstage=dev) the right one is chosen. Also there, when you do devops, essentially the developer choose all parameters and set all URLs and what have you.

This is actually rather common and an area where Java EE has traditionally been lacking, causing a small exodus to other platforms.
Sure, and we can easily support those use cases. But we should also support the use cases, which do still exist, of enterprise developers, or developers building an app that will be deployed in multiple heterogeneous environments. Why limit ourselves to just one use case?

Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.
That option should be taken into account, but as many (web) applications are developed in house and operated by the same company or group that develops it, we have to be careful not to think that deploying the application elsewhere to an unknown site and operated by a separate ops team is the only (or even the most common) use case.
Sure.

Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. 
Indeed, and the generic key/value map enables that.
To a point, but it specifying parameters implies that those parameters are rigid. Leaving it up the the impl allows a single instance of the impl to be flexible and handle a variety of situations.


In the current proposal it's:

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
   
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358",
        "PBKDF2.iterationCount=2048"
    }

A vendor can very easily and transparently extend that with extra parameters, e.g. :

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
    
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358", 
        "PBKDF2.iterationCount=2048"
        "com.oracle.webLogic.middleware.encryption.d2of2.tMinS=5"
    }

Where the extra parameter is used to set the minimal time the algorithm should take before returning.


but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.
As a developer myself and looking back at what my previous teams did, I'm 100% convinced developers do want that ;)
Perhaps, but I'm not sure that always leads to better security. If we make it so they don't have to care, and they know they'll get good security, they won't worry about parameters. Your salt specification above, for example, is an anti-pattern. (Each password should have a different salt -- salt size is the value I'd argue we should support, if anything. If you want an algorithm that uses the same hash for every password, that's something you should have to write yourself.)

Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).
This can still be done, since the parameters can be EL enabled and then fetch the config externally.

Similarly, parameters like the salt and iteration count can be defaulted. That way you can have 3 levels:

1. Specify only the class name; you get defaults for all parameters and it Just Works
2. Specify the parameters locally to match a specific DB or requirement
3. (via EL) fetch the parameter values externally

The most important rule should always be that the developer is in full control, or can be in full control. External overrides should be possible, but never be required. That is -the- big mistake that Java EE made in the past.
I agree, but I think we're only talking about what the mechanism for override is, and what the trade-off between simplicity and the override mechanism is. In practice, I don't think parameters are going to be very helpful to most developers. They can be used to tweak some simple things, but the simple things won't typically be necessary and the more complex things can't be handled by parameters.
 
Could you please provide an example of such a setting, please? Just to better understand. Otherwise, we could just wait for your new proposal to see.




P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).
You mean PBKDF2? That has already been implemented:

@ApplicationScoped
public class Pbkdf2HashAlgorithmImpl implements Pbkdf2HashAlgorithm {
 
    @Override
    public boolean verifyHash(char[] password, String hashedPassword, Map<String, String> parameters) {
        return 
            pbkdf2(
                password, 
                parameters.get("PBKDF2.salt").getBytes(),
                Integer.valueOf(parameters.get("PBKDF2.iterationCount"))
            )
            .equals(hashedPassword);
    }
    
    private String pbkdf2(char[] password, byte[] salt, int iterationCount) {
        try {
            return 
                Base64.getEncoder()
                      .encodeToString(
                          SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                                          .generateSecret(
                                             new PBEKeySpec(password, salt, iterationCount, 64 * 8))
                                          .getEncoded());
            
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new IllegalStateException(e);
        }
    }
    
}

See:

https://github.com/arjantijms/soteria/blob/expression-language/impl/src/main/java/org/glassfish/soteria/identitystores/hash/Pbkdf2HashAlgorithmImpl.java

The API is in javax.security.enterprise.identitystore.Pbkdf2HashAlgorithm combined with a description of the parameters it accepts ("BKDF2.salt" and "PBKDF2.iterationCount"

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Re: LDAP Annotation and Database Hashing Proposal

Guillermo González de Agüero
 



On Thu, Jul 20, 2017 at 4:18 PM, Will Hopkins <will.hopkins@...> wrote:
Catching up on a lot of discussion ...

First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.

I'm still not sold on the interface vs name approach. I personally still prefer the name idea, but with a specific pattern as discussed before, so users just need to know the algorithm name and the runtime will find the implementation. I still don't want to have a hard dependency on a vendor specific class. But on the other hand, I support Arjan's proposal for EL expression returning just the class, which then the implementation can instantiate via CDI lookup.

Sorry for the confusion I may have caused. Waiting for your counterproposal :)
 

Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time. Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.

Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. In fact, we might want to specify a standard "LocalDefault" algorithm, with behavior up to the vendor or site.

Third, "{Algorithm:interations:saltsize}base64(salt):base64(hash)" was never intended as a way to configure algorithm attributes; rather, it was meant to be a standardized storage format for hashed passwords -- one that allowed an implementation determine what parameters to use just by parsing the hashed password, so that an impl could use one set of parameters when generating new password hashes, but continue to be able to verify old passwords that may have been hashed with a different set of parameters. That allows passwords to be updated to stronger security as they are changed.

I actually don't think we should specify a way to configure algorithm parameters. If our goal is simplicity, what's more simple than specifying the name (or IF) of the algorithm you want, and leaving the details up to the algorithm implementation? The problem is that there are so many possible variations we can't specify them all. They will never be portable. If we have to support parameters, then Properties is definitely a good, flexible way to go, but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.

Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).

Thoughts?

Will

P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).



On 07/20/2017 07:33 AM, Arjan Tijms wrote:
Hi,

Okay, as a picture says more than a thousand words I'll prepare a PR for this proposal today or tomorrow.

Thx!

Kind regards,
Arjan Tijms

On Thu, Jul 20, 2017 at 1:28 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

I missed that proposal. Looks good and complete to me, thanks!

Regards,

Guillermo González de Agüero

El jue., 20 jul. 2017 a las 12:38, Arjan Tijms (<arjan.tijms@...>) escribió:
Hi,

On Thu, Jul 20, 2017 at 12:26 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

Yes, your proposal is inline with mine. EL support there would be just a method reference that returns a class.

Good ;)

 

This could be used along my idea of setting just the name of the algorithm and then the runtime checking via "some mechanism" like the proposed string pattern.

Indeed.

 

But aside from that, how do we solve the attribute/configuration problems?

What about my previous proposal where I mention the key/value array?

@DataSourceDefinition uses the same approach:

    /**
     *  Used to specify  Vendor specific properties and less commonly
     * used <code>DataSource</code> properties such as:
     * <p>
     * <ul>
     * <li>dataSourceName
     * <li>networkProtocol
     * <li>propertyCycle
     * <li>roleName
     * </ul>
     * <p>
     *  Properties are specified using the format:
     *  <i>propertyName=propertyValue</i>  with one property per array element.
     * <p>
     * If a DataSource property is specified in the properties
     * element and the annotation element for the  property is also
     * specified, the annotation element value takes precedence.
     * @since 1.1
     */
    String[] properties() default {};


With that you can do:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}"
    hashAlgorithmParameters = { "salt=83689638687683", "iterations=2048" }
)

EL would be naturally supported as well:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}"
    hashAlgorithmParameters = { "salt=83689638687683", "iterations=2048", "#{someBean.myOtherParameters}" }
)

Where the expression can return a String or String[].


Kind regards,
Arjan Tijms




 
Maybe we could resuse Will's original proposal for the algorithm attribute, i.e.: {Algorithm:interations:saltsize}base64(salt):base64(hash)

In that case, when e.g. sha512:50:20base64:base64 is set, the runtime would lookup an "Application_HashAlgorithm_sha512" bean and when not found, a "Server_HashAlgorithm_sha512".

But the options would need to be passed in some way to the interface (maybe as a parameter?).

What do you think?


Regards,

Guillermo González de Agüero

El jue., 20 jul. 2017 a las 11:32, Arjan Tijms (<arjan.tijms@...>) escribió:
Hi,

On Thu, Jul 20, 2017 at 9:50 AM, Guillermo González de Agüero <z06.guillermo@...> wrote:

Applications would become non-portable everytime they need a different algorithm that the only one provided by the spec... or they will need to create a custom implementations, which is really not much better.


Okay, I understand what you mean here.

There's 2 classes (no pun) of provided classes; the ones in external jars that are included with the application, and the ones that the application server vendor provides.

The first case is like adding p:dataTable, the second indeed like persistence.xml for say generating a schema from classes.

The question is if hash algorithms can be sufficiently common wrt configuration that it even makes sense to have a single application support both org.glassfish.XYZAlgo offered by GlassFish and org.jboss.XYZAlgo on JBoss.

What I could think of is having an array of classes and first one available is used.

E.g.

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithm = {JBossSuperAlgorithm.class, GlassFishSuperAlgorithm.class}
)

But the compiler initially would need to have both classes on the compile class path (runtime they don't have to be there). So I don't think that's a good idea.

In this case the EL variant of that attribute may be better:

@DatabaseIdentityStoreDefinition(
    ...
    hashAlgorithmEpression  = "#{someBean.algorithm}" 
)


@Named
@ApplicationScoped
public class SomeBean {

    public Class<? extends HashAlgorithm> algorithm() {
        try {
            return Class.forName("org.jboss.super");
        } catch (...) {}

          try {
            return Class.forName("org.glassfish.super");
        } catch (...) {}

       // ...

    }

Thoughts?

Kind regards,
Arjan Tijms




-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 



On 07/20/2017 10:54 AM, Arjan Tijms wrote:
On Thu, Jul 20, 2017 at 07:18 am, Will Hopkins wrote:
First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.
Ok, good! :)



Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time.
It depends, many applications actually do decide those things and in those applications it are the developers as well who decide this.

In the simplest example, if I'm programming a micro application for IoT (on Raspberry pi) I'm the only developer and my application uses only one LDAP URL.

In a bigger example, when you build and operate your own website (like I did with zeef.com), you only have a select few different LDAP URLs, which are all configured up front in the application, and via a stage parameter (i.e. -Dstage=dev) the right one is chosen. Also there, when you do devops, essentially the developer choose all parameters and set all URLs and what have you.

This is actually rather common and an area where Java EE has traditionally been lacking, causing a small exodus to other platforms.
Sure, and we can easily support those use cases. But we should also support the use cases, which do still exist, of enterprise developers, or developers building an app that will be deployed in multiple heterogeneous environments. Why limit ourselves to just one use case?

Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.
That option should be taken into account, but as many (web) applications are developed in house and operated by the same company or group that develops it, we have to be careful not to think that deploying the application elsewhere to an unknown site and operated by a separate ops team is the only (or even the most common) use case.
Sure.

Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. 
Indeed, and the generic key/value map enables that.
To a point, but it specifying parameters implies that those parameters are rigid. Leaving it up the the impl allows a single instance of the impl to be flexible and handle a variety of situations.


In the current proposal it's:

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
   
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358",
        "PBKDF2.iterationCount=2048"
    }

A vendor can very easily and transparently extend that with extra parameters, e.g. :

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
    
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358", 
        "PBKDF2.iterationCount=2048"
        "com.oracle.webLogic.middleware.encryption.d2of2.tMinS=5"
    }

Where the extra parameter is used to set the minimal time the algorithm should take before returning.


but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.
As a developer myself and looking back at what my previous teams did, I'm 100% convinced developers do want that ;)
Perhaps, but I'm not sure that always leads to better security. If we make it so they don't have to care, and they know they'll get good security, they won't worry about parameters. Your salt specification above, for example, is an anti-pattern. (Each password should have a different salt -- salt size is the value I'd argue we should support, if anything. If you want an algorithm that uses the same hash for every password, that's something you should have to write yourself.)

Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).
This can still be done, since the parameters can be EL enabled and then fetch the config externally.

Similarly, parameters like the salt and iteration count can be defaulted. That way you can have 3 levels:

1. Specify only the class name; you get defaults for all parameters and it Just Works
2. Specify the parameters locally to match a specific DB or requirement
3. (via EL) fetch the parameter values externally

The most important rule should always be that the developer is in full control, or can be in full control. External overrides should be possible, but never be required. That is -the- big mistake that Java EE made in the past.
I agree, but I think we're only talking about what the mechanism for override is, and what the trade-off between simplicity and the override mechanism is. In practice, I don't think parameters are going to be very helpful to most developers. They can be used to tweak some simple things, but the simple things won't typically be necessary and the more complex things can't be handled by parameters.



P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).
You mean PBKDF2? That has already been implemented:

@ApplicationScoped
public class Pbkdf2HashAlgorithmImpl implements Pbkdf2HashAlgorithm {
 
    @Override
    public boolean verifyHash(char[] password, String hashedPassword, Map<String, String> parameters) {
        return 
            pbkdf2(
                password, 
                parameters.get("PBKDF2.salt").getBytes(),
                Integer.valueOf(parameters.get("PBKDF2.iterationCount"))
            )
            .equals(hashedPassword);
    }
    
    private String pbkdf2(char[] password, byte[] salt, int iterationCount) {
        try {
            return 
                Base64.getEncoder()
                      .encodeToString(
                          SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                                          .generateSecret(
                                             new PBEKeySpec(password, salt, iterationCount, 64 * 8))
                                          .getEncoded());
            
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new IllegalStateException(e);
        }
    }
    
}

See:

https://github.com/arjantijms/soteria/blob/expression-language/impl/src/main/java/org/glassfish/soteria/identitystores/hash/Pbkdf2HashAlgorithmImpl.java

The API is in javax.security.enterprise.identitystore.Pbkdf2HashAlgorithm combined with a description of the parameters it accepts ("BKDF2.salt" and "PBKDF2.iterationCount"

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: Packaging bundle vs jar

Werner Keil
 

If you use Apache Felix, then sure, "bundle" is perfectly fine.

Works for JSRs like 363: https://github.com/unitsofmeasurement/unit-ri/blob/master/pom.xml
or 354: https://github.com/JavaMoney/jsr354-ri/blob/master/pom.xml

Werner


Re: Packaging bundle vs jar

Will Hopkins
 

What we really need is the OSGi manifest information, but choosing "bundle" seemed like the easiest way to get that.

It had previously been set as "bundle", and the GF integration was working. Was there a reason for the change to "jar"?

On 07/20/2017 11:16 AM, Arjan Tijms wrote:
Hi,

I noticed this commit: https://github.com/javaee-security-spec/soteria/commit/421b6f001c31cd3d64bad0b0f62807ebbb1c7712

Where the comment said "bundle" is needed for GF integration. However JSF/Mojarra used "jar", and obviously has been integrated in GF as well.

The bundle (OSGi) information (MANIFEST.MF mostly) should be added to the jar, even without the maven project type being "bundle". 

Wondering what problems were exactly encountered, but I'm fairly sure packaging "bundle" should not be needed as I integrated Soteria into Payara without any issues.

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 



On 07/20/2017 11:00 AM, Arjan Tijms wrote:
On Thu, Jul 20, 2017 at 07:28 am, Will Hopkins wrote:
That's what I get for sleeping for a couple hours ... ;)
Ah, you hadn't seen that one yet, that explains some of the previous mail ;) Well, people need sleep too :P



Need to review this carefully, but initial thoughts:
  • If IdentityHashAlgorithm is meant to be a plaintext compare, then NullHashAlgorithm might communicate that more explicitly.

Could be, indeed. Or NoopHashAlgorithm. "Identity" was chosen though based on the usage of that term in the Function interface (a t -> t, or returning what's being used as input, see https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#identity--
Yup, I did get the sense in which "identity" was meant in that context, and it's appropriate. But in the context of IdentityStores the word "Identity" shows up a lot, so it's a bit overloaded here. That's why I thought "Null" (or "Noop") might be better.




  • We should support a generate() method as well as a verify() method. The default impl won't need it, but it should be available in a standard way for impls that want to do that.

Sure,  we could include it.


  • I don't think we should pass the parameters to the verify() method. If we pass them at all, it should be to initialize the HashAlgorithm. The verify() method might actually need to use a completely different set of parameters, as determined by the encoded hash value.
I've been thinking about it, and actually had a version locally where it did set them at construction time (using a Producer so it could be injected), but to support deferred EL expressions and keeping EL details away from the algorithm (it just sees the result), passing the parameters in every time is quite a bit more flexible and easier too.
But it either limits what the method can do, or it's redundant. As you'll see when I propose an impl, I think we can do something much more powerful without needing to pass in parameters.

Will


Kind regards,
Arjan Tijms



Will


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Packaging bundle vs jar

Arjan Tijms
 

Hi,

I noticed this commit: https://github.com/javaee-security-spec/soteria/commit/421b6f001c31cd3d64bad0b0f62807ebbb1c7712

Where the comment said "bundle" is needed for GF integration. However JSF/Mojarra used "jar", and obviously has been integrated in GF as well.

The bundle (OSGi) information (MANIFEST.MF mostly) should be added to the jar, even without the maven project type being "bundle". 

Wondering what problems were exactly encountered, but I'm fairly sure packaging "bundle" should not be needed as I integrated Soteria into Payara without any issues.

Kind regards,
Arjan Tijms


Re: LDAP Annotation and Database Hashing Proposal

Arjan Tijms
 

On Thu, Jul 20, 2017 at 07:28 am, Will Hopkins wrote:
That's what I get for sleeping for a couple hours ... ;)
Ah, you hadn't seen that one yet, that explains some of the previous mail ;) Well, people need sleep too :P



Need to review this carefully, but initial thoughts:
  • If IdentityHashAlgorithm is meant to be a plaintext compare, then NullHashAlgorithm might communicate that more explicitly.
Could be, indeed. Or NoopHashAlgorithm. "Identity" was chosen though based on the usage of that term in the Function interface (a t -> t, or returning what's being used as input, see https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#identity--



  • We should support a generate() method as well as a verify() method. The default impl won't need it, but it should be available in a standard way for impls that want to do that.
Sure,  we could include it.


  • I don't think we should pass the parameters to the verify() method. If we pass them at all, it should be to initialize the HashAlgorithm. The verify() method might actually need to use a completely different set of parameters, as determined by the encoded hash value.
I've been thinking about it, and actually had a version locally where it did set them at construction time (using a Producer so it could be injected), but to support deferred EL expressions and keeping EL details away from the algorithm (it just sees the result), passing the parameters in every time is quite a bit more flexible and easier too.

Kind regards,
Arjan Tijms



Will


Re: LDAP Annotation and Database Hashing Proposal

Arjan Tijms
 

On Thu, Jul 20, 2017 at 07:18 am, Will Hopkins wrote:
First, it seems there's a strong consensus for using IF types instead of names. I still have reservations, but I'm OK moving forward with that.
Ok, good! :)



Second, I'd like to reiterate that I don't see what we're doing as providing a mechnism to specify a small set of common, and commonly used, algorithms. Yes, there will be some of that. But equally, there will be a lot of site- and application-specific algorithms.

This will be like configuring LDAP or Database parameters in many instances. An application doesn't decide up front which LDAP URL it's going to use, or what the bindDN is -- it configures those things at deployment time.
It depends, many applications actually do decide those things and in those applications it are the developers as well who decide this.

In the simplest example, if I'm programming a micro application for IoT (on Raspberry pi) I'm the only developer and my application uses only one LDAP URL.

In a bigger example, when you build and operate your own website (like I did with zeef.com), you only have a select few different LDAP URLs, which are all configured up front in the application, and via a stage parameter (i.e. -Dstage=dev) the right one is chosen. Also there, when you do devops, essentially the developer choose all parameters and set all URLs and what have you.

This is actually rather common and an area where Java EE has traditionally been lacking, causing a small exodus to other platforms. 

Similarly, applications may have to configure a custom hashing algorithm at deployment time, in order to support the existing user store on site, and the configured value won't be PBKDF2 or Argon2, it'll be AcmeCorpCustomHashAlgorithm.
That option should be taken into account, but as many (web) applications are developed in house and operated by the same company or group that develops it, we have to be careful not to think that deploying the application elsewhere to an unknown site and operated by a separate ops team is the only (or even the most common) use case.



Similarly, I'm assuming an implementation of the default PBKDF2 would have to implement some standard behaviors by default, but could also support, as value add, encodings and parameter settings not specified by the standard. 
Indeed, and the generic key/value map enables that.

In the current proposal it's:

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
   
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358",
        "PBKDF2.iterationCount=2048"
    }

A vendor can very easily and transparently extend that with extra parameters, e.g. :

@DatabaseIdentityStoreDefinition(
    dataSourceLookup="${'java:global/MyDS'}", 
    callerQuery="#{'select password from caller where name = ?'}",
    groupsQuery="select group_name from caller_groups where caller_name = ?",
    
    hashAlgorithm = Pbkdf2HashAlgorithmImpl.class,
    hashAlgorithmParameters = {
        "PBKDF2.salt=38687585358", 
        "PBKDF2.iterationCount=2048"
        "com.oracle.webLogic.middleware.encryption.d2of2.tMinS=5"
    }

Where the extra parameter is used to set the minimal time the algorithm should take before returning.


but I'd argue that you don't want developers specifying that level of detail. For the few cases where they really want/need to, they can write a HashAlgorithm instance to do what they want.
As a developer myself and looking back at what my previous teams did, I'm 100% convinced developers do want that ;)


Leaving the behavior up to the implementation will allow platforms and deployment environments to provide algorithm implementations that are flexible and support specific -- and possibly variable -- requirements, without exposing that complexity to the application. Part of my thinking with this was to completely externalize all those details, with the app knowing nothing but the name of an implementation (or, now, the classname).
This can still be done, since the parameters can be EL enabled and then fetch the config externally.

Similarly, parameters like the salt and iteration count can be defaulted. That way you can have 3 levels:

1. Specify only the class name; you get defaults for all parameters and it Just Works
2. Specify the parameters locally to match a specific DB or requirement
3. (via EL) fetch the parameter values externally

The most important rule should always be that the developer is in full control, or can be in full control. External overrides should be possible, but never be required. That is -the- big mistake that Java EE made in the past.


P.S., I'd like to take a shot at implementing the default HashAlgorithm class (and API code).
You mean PBKDF2? That has already been implemented:

@ApplicationScoped
public class Pbkdf2HashAlgorithmImpl implements Pbkdf2HashAlgorithm {
 
    @Override
    public boolean verifyHash(char[] password, String hashedPassword, Map<String, String> parameters) {
        return 
            pbkdf2(
                password, 
                parameters.get("PBKDF2.salt").getBytes(),
                Integer.valueOf(parameters.get("PBKDF2.iterationCount"))
            )
            .equals(hashedPassword);
    }
    
    private String pbkdf2(char[] password, byte[] salt, int iterationCount) {
        try {
            return 
                Base64.getEncoder()
                      .encodeToString(
                          SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                                          .generateSecret(
                                             new PBEKeySpec(password, salt, iterationCount, 64 * 8))
                                          .getEncoded());
            
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new IllegalStateException(e);
        }
    }
    
}

See:

https://github.com/arjantijms/soteria/blob/expression-language/impl/src/main/java/org/glassfish/soteria/identitystores/hash/Pbkdf2HashAlgorithmImpl.java

The API is in javax.security.enterprise.identitystore.Pbkdf2HashAlgorithm combined with a description of the parameters it accepts ("BKDF2.salt" and "PBKDF2.iterationCount"

Kind regards,
Arjan Tijms


Re: WARNING! PLEASE READ! (Was: Fwd: Re: [javaee-security-spec] Moving to Java EE Github?)

Will Hopkins
 

I thought I sent this out yesterday, but forgot to copy the list -- just as well that I wasn't able to complete the migration last night, although I did get started on the security-spec repo.

Please note the part about issue management -- I think it will be helpful to use issues to track what we're working on, to avoid duplicate effort or working at cross purposes -- for now, lets use soteria repo issues to track who's working on tasks.

Will

On 07/19/2017 12:49 PM, Will Hopkins wrote:
MOVING THE REPOS TODAY!

Unless there are objections, I plan to migrate the security-spec, security-api, and soteria repos to the Java EE github organization today. Since most of you are in Europe, I'll do it during the evening my time, which will be very late at night CET.

Before doing so, I'll disable access for everyone, to avoid interrupting a commit or an issue update. Once everything is successfully migrated, I'll re-enable access on the Java EE side.

ISSUE MANAGEMENT:

On a slightly different topic, I plan to triage the outstanding Issues for both security-spec (@javaee org) and soteria, and use them to manage the remaining work. Please plan to track work you're doing with github issues. I'll send a more detailed email on this topic soon.

Regards,

Will


-------- Forwarded Message --------
Subject: Re: [javaee-security-spec] Moving to Java EE Github?
Date: Tue, 18 Jul 2017 22:13:12 -0400
From: Will Hopkins <will.hopkins@...>
To: javaee-security-spec@javaee.groups.io


I think I'm about ready to migrate the repos to the javaee organization.

If anyone has work in flight that will be disrupted, please let me know. Otherwise, I'll plan to do the migration sometime tomorrow (Wednesday, 7/19).

The plan is to migrate as follows:
  • security-spec -> javaee/security-spec
    • issues are already there (migrated from java.net)
    • migrate the source only, using git clone
    • recreate releases based on migrated tags at the destination
    • will lose pull-request history, but should preserve everything else we need.
git clone --bare $GITHUB_URL_OLD_REPO
cd <repo-name>.git
git push --mirror $GITHUB_URL_NEW_REPO
  • security-api -> javaee/security-api
    • use github "transfer" function to migrate entire repo
  • soteria -> javaee/security-ri-soteria
    • use github "transfer function to migrate  entire repo
    • rename repo when transfer completes

I'll make a full (bare) clone of each repo before transferring it.

Seem like a reasonable plan?

Will




On 07/11/2017 02:21 PM, Werner Keil wrote:
Ok, let us know, if you need any help by those who have the necessary rights.

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 

I'll code something up today as a counterproposal.

On 07/20/2017 10:27 AM, Will Hopkins wrote:
That's what I get for sleeping for a couple hours ... ;)

Need to review this carefully, but initial thoughts:
  • If IdentityHashAlgorithm is meant to be a plaintext compare, then NullHashAlgorithm might communicate that more explicitly.
  • We should support a generate() method as well as a verify() method. The default impl won't need it, but it should be available in a standard way for impls that want to do that.
  • I don't think we should pass the parameters to the verify() method. If we pass them at all, it should be to initialize the HashAlgorithm. The verify() method might actually need to use a completely different set of parameters, as determined by the encoded hash value.

Will


On 07/20/2017 10:13 AM, Arjan Tijms wrote:
Hi,

I just did 2 PRs with the above sketched proposals:

https://github.com/javaee-security-spec/security-api/pull/46
https://github.com/javaee-security-spec/soteria/pull/113

I haven't EL enabled the attributes yet, but that should not be much extra work.

Looking forward to hearing your thoughts on those.

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Re: LDAP Annotation and Database Hashing Proposal

Will Hopkins
 

That's what I get for sleeping for a couple hours ... ;)

Need to review this carefully, but initial thoughts:
  • If IdentityHashAlgorithm is meant to be a plaintext compare, then NullHashAlgorithm might communicate that more explicitly.
  • We should support a generate() method as well as a verify() method. The default impl won't need it, but it should be available in a standard way for impls that want to do that.
  • I don't think we should pass the parameters to the verify() method. If we pass them at all, it should be to initialize the HashAlgorithm. The verify() method might actually need to use a completely different set of parameters, as determined by the encoded hash value.

Will


On 07/20/2017 10:13 AM, Arjan Tijms wrote:
Hi,

I just did 2 PRs with the above sketched proposals:

https://github.com/javaee-security-spec/security-api/pull/46
https://github.com/javaee-security-spec/soteria/pull/113

I haven't EL enabled the attributes yet, but that should not be much extra work.

Looking forward to hearing your thoughts on those.

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803

281 - 300 of 736