On 16/09/2014 16:20, Christopher Schultz wrote:
> All,
> 
> In reference to bug 56403
> (https://issues.apache.org/bugzilla/show_bug.cgi?id=56403) and
> specifically markt's proposed patch
> (http://people.apache.org/~markt/patches/2014-09-16-bug56403-tc8-v1.patch),
> I have the following comments.
> 
> I'm interested in what others have to say.
> 
> 1. In terms of limiting converting to String values, we could base
> everything on byte[] instead of String. That also makes it possible to
> blank-out the credential arrays when we are done with them, slightly
> improving security; as long as the j_password is never retrieved using
> HttpServletRequest.getParameter, we can avoid String values entirely and
> purge the characters from memory as soon as we are done. Nothing that I
> know of can stop the memory manager from re-locating byte arrays in
> memory (short of using native code to temporarily pin them, but that
> gets very dangerous and messy).

No objections to this if it is doable without too much impact to the
existing code but:
a) I'm not convinced it is worth it
b) I want to look at when the String -> bytes conversions would need to
take place.

> 2. I don't like CredentialHandler.mutate(String input, byte[] salt, int
> iterations). I think it ties the method signature to the implementation
> of the mutation algorithm. PBKDF2 for instance has both "salt" and
> "iterations", but straight-up MD5 (e.g. our existing implementation)
> does not. Also, non-hashing algorithms like any symmetric encryption
> algorithm (e.g. AES, Blowfish, etc.) does not have such parameters, and
> would require instead an encryption key. I think that mutate() should
> only take a single argument but also have setters that can be called
> from configuration, like this:
> 
>   <Realm>
>     <CredentialHandler class="PBKDF2" saltSize="8" iterations="50000" />
>   </Realm>
> 
> In this case, the PBKDF2 class would have a setIterations(int) method
> and a setSaltSize(int) method to set the number of salt bytes to use.
> 
> If we want the implementations for MessageDigest-based handlers as well
> as things like PBKDF2 to extend the same base class that provides lots
> of utility methods, that's find. I just don't like tying the interface
> itself for the matches() method to a particular style of implementation.

I take the point but having fixed values for saltSize and iterations
then limits you to using the same values for every entry in the Realm
which creates a different set of issues. I'm not sure there is an API
that can meet all those requirements but it is worth spending some time
thinking about it.

> 3. MessageDigestCredentialHandler is good, but I think we ought to
> push-down the iteration and salt members and methods from
> BaseCredentialHandler into the subclass.

Fair point if we start having CredentialHandlers based on symmetric
encryption. I'm not convinced that is a good idea but I take the point.

> 4. In MessageDigestCredentialHandler.matches, there are two uses of
> StandardCharsets.ISO_8859_1 directly instead of using the client's
> preferred character encoding. Is this a requirement of {MD5|SHA|SSHA}
> formatting or an oversight?

Don't know. It is what the current code does so I am reluctant to change
it without a report that something is broken.

> 5. matchesSaltIterationsEncoded method does not check for unexpected
> formatting. Specifically, the values for sep1 and sep2 are never checked
> to see if they are positive or that sep1 < sep2. I'm not sure which
> would be better: StringArrayIndexOutOfBoundsException from the JVM or
> something a little more nuanced from the CredentialHandler itself. The
> JVM is going to perform the checks anyway... should we waste a few
> cycles to check these values ourselves and throw a different kind of
> exception, or is it unnecessary? (I suppose try/catch could be used to
> convert SAIOOBE into something else with a better error message, but
> try/catch has its own overhead as well).

We should probably log a warning message for the sys admin.

> 6. Performance. There are places where we know the sizes of things
> before they are allocated but don't use that to our advantage. An
> example from CredentialHandlerBase.generate:
> 
>   return HexUtils.toHexString(salt) + "$" + iterations + "$" +
> serverCredential;
> 
> We know in advance the exact length of the string we need, but the
> compiler will use a StringBuilder with a default capacity (16 characters
> in Oracle Java 7). It would be better to pre-allocate the buffer we need:
> 
>   StringBuilder credential = new StringBuilder(saltLength << 1 +
> serverCredential.length() + 10 + 2);
>   credential.append(HexUtils.toString(salt))
>             .append('$')
>             .append(iterations)
>             .append('$')
>             .append(serverCredential);
> 
>   return credential.toString();

Fair enough.

> I'm not sure if it matters too much, but a bit of space could be saved
> by storing the iterations in hex encoding as well (max 8 characters
> instead of 10).

No strong opinion.

> 7. Thread safety. Is it safe to check/set the "random" reference in
> multiple threads? I suppose the worse thing that could happen would be
> to create more SecureRandom objects than strictly necessary.

It is only used in off-line mode so I think this is safe.

> 8. RealmBase.main checks all known CredentialHandlers for matching
> algorithms (a bit inefficient, but its offline so who cares), but it
> doesn't know about anyone's custom CH classes. We should allow the
> caller to specify the CH class if they want, so they can use the
> RealmBase driver with their own CredentiaHandler implementation.

That is doable but it raises some of the issues you've highlighted in 2)
and 3) above.

> I'm sure I'll come up with other comments later, but this ought to get
> the ball rolling.


> 
> Thanks,
> -chris
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to