Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Bradford Wetmore

> I still need an official reviewer.

Thanks for looking into this, I was going check into it today if you 
didn't.  I figured it must be something in byte comparison.  Sure enough.


Good catches!  :)  That code's been in there a long time!

Only nit is Copyright Dates if you choose to update.

Rest looks good.

Brad


On 5/6/2014 6:43 AM, Xuelei Fan wrote:

On 5/6/2014 9:39 PM, Florian Weimer wrote:

On 05/06/2014 03:37 PM, Xuelei Fan wrote:

On 5/6/2014 9:31 PM, Florian Weimer wrote:

On 05/06/2014 02:00 PM, Xuelei Fan wrote:


Storing both int version and major/minor byte versions is a little bit
redundancy.  The update is significant.  I will focus on the signed
byte
issue in this fix.


Yes, I get that.  I've verified that you've covered all the version
comparisons.



Thanks for the code review.  Do you have a OpenJDK author account?


I'm not an official reviewer, I'm afraid.


I will your name in a "also reviewed by" section.  I still need an
official reviewer.

Thanks,
Xuelei



Re: Review Request of JDK Enhancement Proposal: OCSP stapling

2014-05-06 Thread Xuelei Fan
On 5/6/2014 9:36 PM, Florian Weimer wrote:
> On 04/02/2014 01:19 AM, Xuelei Fan wrote:
>> Here is the updated version:
>>http://cr.openjdk.java.net/~xuelei/8034248/jep-csre-v01.txt
>>
>> Updated the description section and a few words so that it is easier to
>> understand.
> 
> I think the server side would benefit from an API which allows code to
> directly supply the OCSP response to be stapled, perhaps as part of the
> extended trust manager.
> 
Typically, OCSP response is time-variant.  Ideally, the response should
be retrieved and updated internally, in time and automatically.  For the
first stage, I only want to implement the essential feature, and keep
the footprint as small as possible.

Thanks,
Xuelei


Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Xuelei Fan
On 5/6/2014 9:31 PM, Florian Weimer wrote:
> On 05/06/2014 02:00 PM, Xuelei Fan wrote:
> 
>> Storing both int version and major/minor byte versions is a little bit
>> redundancy.  The update is significant.  I will focus on the signed byte
>> issue in this fix.
> 
> Yes, I get that.  I've verified that you've covered all the version
> comparisons.
> 
Thanks for the code review.  Do you have a OpenJDK author account?

> I was just wondering if accessor methods (or storing the values as ints)
> would make it less likely that the issue reoccurs in a different
> variant.
I think, it should be better.

Thanks,
Xuelei

> But the new checkRecordVersion() probably covers that.
> 



Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Florian Weimer

On 05/06/2014 03:37 PM, Xuelei Fan wrote:

On 5/6/2014 9:31 PM, Florian Weimer wrote:

On 05/06/2014 02:00 PM, Xuelei Fan wrote:


Storing both int version and major/minor byte versions is a little bit
redundancy.  The update is significant.  I will focus on the signed byte
issue in this fix.


Yes, I get that.  I've verified that you've covered all the version
comparisons.



Thanks for the code review.  Do you have a OpenJDK author account?


I'm not an official reviewer, I'm afraid.

I used to have an author account (fweimer), but can no longer access it.

--
Florian Weimer / Red Hat Product Security Team


Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Xuelei Fan
On 5/6/2014 9:39 PM, Florian Weimer wrote:
> On 05/06/2014 03:37 PM, Xuelei Fan wrote:
>> On 5/6/2014 9:31 PM, Florian Weimer wrote:
>>> On 05/06/2014 02:00 PM, Xuelei Fan wrote:
>>>
 Storing both int version and major/minor byte versions is a little bit
 redundancy.  The update is significant.  I will focus on the signed
 byte
 issue in this fix.
>>>
>>> Yes, I get that.  I've verified that you've covered all the version
>>> comparisons.
> 
>> Thanks for the code review.  Do you have a OpenJDK author account?
> 
> I'm not an official reviewer, I'm afraid.
> 
I will your name in a "also reviewed by" section.  I still need an
official reviewer.

Thanks,
Xuelei



Re: Review Request of JDK Enhancement Proposal: OCSP stapling

2014-05-06 Thread Florian Weimer

On 04/02/2014 01:19 AM, Xuelei Fan wrote:

Here is the updated version:
   http://cr.openjdk.java.net/~xuelei/8034248/jep-csre-v01.txt

Updated the description section and a few words so that it is easier to
understand.


I think the server side would benefit from an API which allows code to 
directly supply the OCSP response to be stapled, perhaps as part of the 
extended trust manager.


--
Florian Weimer / Red Hat Product Security Team


Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Florian Weimer

On 05/06/2014 02:00 PM, Xuelei Fan wrote:


Storing both int version and major/minor byte versions is a little bit
redundancy.  The update is significant.  I will focus on the signed byte
issue in this fix.


Yes, I get that.  I've verified that you've covered all the version 
comparisons.


I was just wondering if accessor methods (or storing the values as ints) 
would make it less likely that the issue reoccurs in a different 
variant.  But the new checkRecordVersion() probably covers that.


--
Florian Weimer / Red Hat Product Security Team


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Xuelei Fan
On 5/6/2014 9:01 PM, Florian Weimer wrote:
>> When the implementation of the underlying is unknown, it is hard to
>> estimate the detailed behavior in the unknown black box.
> 
> True.  So you think providing more efficient means for hashing
> relatively short byte sequences isn't worth the effort?
The benefits are small, I think.  It is easy to get similar improvement
in application layer, but if we want add this to JRE for general use, we
may need to evaluation too much uncertainties or limitations.

Xuelei


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Florian Weimer

On 05/06/2014 02:35 PM, Xuelei Fan wrote:


When I though about the case, the idea come to my mind was that the
clone() may need to use the current states of MD.  It is great if all of
the current states can also be cloned to another session.  But ...


The PKCS#11 provider can do this.  The session is initialized lazily, so 
that it doesn't have to be cloned at all if no data has been hashed yet. 
 As far as I can tell, you end up with the same token no matter how the 
digest object is created (after all, there might be only one in the 
system), which probably incurs some synchronization overhead.  But it 
doesn't matter if you use cloning or not.  Allocation is always kind of 
expensive because of the finalization requirement.



When the implementation of the underlying is unknown, it is hard to
estimate the detailed behavior in the unknown black box.


True.  So you think providing more efficient means for hashing 
relatively short byte sequences isn't worth the effort?


--
Florian Weimer / Red Hat Product Security Team


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Xuelei Fan
>> Per the spec, clone() may throw CloneNotSupportedException. It is OK a
>> certain provider does not support Cloneable.
> 
> The key part is that the behavior has to be consistent across all
> objects.  It's not required that clone() works, but if it works for one
> instance, it works for all of them.
> 
True.

>>> The
>>> TLS implementation also relies on this behavior (i.e. clone() either
>>> consistently fails or consistently succeeds).
>>>
>> That's true. SunJSSE requires cloneable MD implementation.
> 
> Are you sure?  It contains a fairly elaborate workaround for the
> non-cloneable case (construct as many digest objects as needed, and then
> feed them data in parallel so that you can finalize one pseudo-clone,
> but continue hashing using the other one).
> 
Right. You got it!  That's also what I mean with "cloneable".

 BTW! I guess in some situation or some providers, clone() might not be
 a lightweight operation.
>>>
>>> Hmm.  I can see that the state cannot be cloned at all (that's why
>>> cloning is optional), but allocating a new state has to happen anyway,
>>> no matter how the object is constructed.
>>>
>> Let's consider a case, every MD object should be bound to a session, and
>> the operations should be synchronized in the session. clone() will share
>> the session, the operations among different MD objects that share the
>> session need to be synchronized.  I think, there is a significant
>> performance and scalablity impact if StandardMessageDigests is used for
>> such cases in concurrency context.
> 
> Why would clone() share the session, but constructing a new digest would
> not?  Because sharing the session would be the only way to share the
> state?  Ugh, yes, you might be right.
> 
When I though about the case, the idea come to my mind was that the
clone() may need to use the current states of MD.  It is great if all of
the current states can also be cloned to another session.  But ...

When the implementation of the underlying is unknown, it is hard to
estimate the detailed behavior in the unknown black box.

Xuelei


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Florian Weimer

On 05/06/2014 01:39 PM, Xuelei Fan wrote:

Another concern of mine is about that the returned MessageDigest object
heavily depends on the providers configuration when the object get
instantiated for the 1st time.  If the providers configuration get
updated during run time, the provider of the returned MessageDigest
object does not get updated accordingly.  This proposal may be a pretty
good practice in application layer in some circumstance, but may result
in unnecessary complexity in JRE layer because we don't know the exact
context that the application want to use this class, and the exact
implementation details of the underlying MD service provider.


Hmm.  It would certainly be possible to invalidate the cache if the 
provider configuration is changed.


It's unlikely that a library-based reimplementation could get this right.


Per the spec, clone() may throw CloneNotSupportedException. It is OK a
certain provider does not support Cloneable.


The key part is that the behavior has to be consistent across all 
objects.  It's not required that clone() works, but if it works for one 
instance, it works for all of them.



The
TLS implementation also relies on this behavior (i.e. clone() either
consistently fails or consistently succeeds).


That's true. SunJSSE requires cloneable MD implementation.


Are you sure?  It contains a fairly elaborate workaround for the 
non-cloneable case (construct as many digest objects as needed, and then 
feed them data in parallel so that you can finalize one pseudo-clone, 
but continue hashing using the other one).



If the performance can get improvement here by define a static cloneable
object, it might be also can get improvement in the same way in the
provider implementation, unless the improvement is all about
implementation service look up among the supported providers.


It's the service lookup.  Well, it was the service lookup in 2010.


BTW! I guess in some situation or some providers, clone() might not be
a lightweight operation.


Hmm.  I can see that the state cannot be cloned at all (that's why
cloning is optional), but allocating a new state has to happen anyway,
no matter how the object is constructed.


Let's consider a case, every MD object should be bound to a session, and
the operations should be synchronized in the session. clone() will share
the session, the operations among different MD objects that share the
session need to be synchronized.  I think, there is a significant
performance and scalablity impact if StandardMessageDigests is used for
such cases in concurrency context.


Why would clone() share the session, but constructing a new digest would 
not?  Because sharing the session would be the only way to share the 
state?  Ugh, yes, you might be right.



What I meant is that there might be no place to store the reference to a
long-term MessageDigest object which is reused again and again, so the
best thing the code can do is to allocate a fresh object when it is needed?


The object of MessageDigest is not immutable.  IMHO, as we discussed
above, there are a lot of issues need to be considered carefully to
support such a long-term object in JRE.


I meant a method like this:

   public static byte[] sha1(byte[] buffer, int offset, int length) {
   MessageDigest md = threadLocalMDs.sha1();
   md.update(buffer, offset, length);
   return md.digest();
   }

The actual digest object would not be exposed through this interface. 
This would cover the use case of hashing short buffers, where the 
instantiation overhead is most visible.



--
Florian Weimer / Red Hat Product Security Team


Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Xuelei Fan
On 5/6/2014 7:41 PM, Florian Weimer wrote:
> On 05/06/2014 12:10 PM, Xuelei Fan wrote:
> 
>> Please review this simple but interesting fix:
>>http://cr.openjdk.java.net/~xuelei/8042449/webrev.00/
> 
> It's strange that the code caches the major/minor version components as
> fields of ProtocolVersion, but these fields cannot be used directly and
> still need shifting and masking.
> 
> Maybe it's better to store the components as ints, or remove the fields
> completely and use accessors that extract the components from the
> version field as needed?
> 
We need to convert the byte and int type back-and-forth.  Store as ints
is convenient for comparing.  Store as bytes is convenient for assigning
to a new generated record.

Storing both int version and major/minor byte versions is a little bit
redundancy.  The update is significant.  I will focus on the signed byte
issue in this fix.

Thanks for the comment!

Xuelei


Re: Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Florian Weimer

On 05/06/2014 12:10 PM, Xuelei Fan wrote:


Please review this simple but interesting fix:
   http://cr.openjdk.java.net/~xuelei/8042449/webrev.00/


It's strange that the code caches the major/minor version components as 
fields of ProtocolVersion, but these fields cannot be used directly and 
still need shifting and masking.


Maybe it's better to store the components as ints, or remove the fields 
completely and use accessors that extract the components from the 
version field as needed?


--
Florian Weimer / Red Hat Product Security Team


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Xuelei Fan
Another concern of mine is about that the returned MessageDigest object
heavily depends on the providers configuration when the object get
instantiated for the 1st time.  If the providers configuration get
updated during run time, the provider of the returned MessageDigest
object does not get updated accordingly.  This proposal may be a pretty
good practice in application layer in some circumstance, but may result
in unnecessary complexity in JRE layer because we don't know the exact
context that the application want to use this class, and the exact
implementation details of the underlying MD service provider.

On 5/6/2014 5:45 PM, Florian Weimer wrote:
> On 05/05/2014 04:43 PM, Xuelei Fan wrote:
> 
>>> It's 10% faster, even including the digest overhead for a
>>> single-block message.
> 
>> clone() is an optional operation for MD. This point may make this
>> class unreliable.
> 
> I think the MessageDigest specification requires that this works.
Per the spec, clone() may throw CloneNotSupportedException. It is OK a
certain provider does not support Cloneable.

> The
> TLS implementation also relies on this behavior (i.e. clone() either
> consistently fails or consistently succeeds).
> 
That's true. SunJSSE requires cloneable MD implementation.

> Note that I'm not blindly calling clone(), I'm providing a fallback in
> case clone() does not work.
> 
It's a good workaround.

>> I think it might be a better place to make the improvement in crypto
>> providers.
> 
> What kind of improvement are you thinking of?
> 
If the performance can get improvement here by define a static cloneable
object, it might be also can get improvement in the same way in the
provider implementation, unless the improvement is all about
implementation service look up among the supported providers.

>> BTW! I guess in some situation or some providers, clone() might not be
>> a lightweight operation.
> 
> Hmm.  I can see that the state cannot be cloned at all (that's why
> cloning is optional), but allocating a new state has to happen anyway,
> no matter how the object is constructed.
> 
Let's consider a case, every MD object should be bound to a session, and
the operations should be synchronized in the session. clone() will share
the session, the operations among different MD objects that share the
session need to be synchronized.  I think, there is a significant
performance and scalablity impact if StandardMessageDigests is used for
such cases in concurrency context.

>>> I think the single-block hashing case is important because it is not
>>> always possible to reuse an existing digest object after calling
>>> reset().
> 
>> It means the reset() does not work.   Looks like a bug to me.
> 
> What I meant is that there might be no place to store the reference to a
> long-term MessageDigest object which is reused again and again, so the
> best thing the code can do is to allocate a fresh object when it is needed?
> 
The object of MessageDigest is not immutable.  IMHO, as we discussed
above, there are a lot of issues need to be considered carefully to
support such a long-term object in JRE.

Thanks,
Xuelei

> Hmm, maybe we could provide a tread-local message digest that can be
> used to hash byte arrays?  It would address the simplest possible case
> where the instantiation overhead is most visible.
> 



Code review request [JDK 9] 8042449 Issue for negative byte major record version

2014-05-06 Thread Xuelei Fan
Hi,

Please review this simple but interesting fix:
  http://cr.openjdk.java.net/~xuelei/8042449/webrev.00/

During the checking of invalid record version, a byte to byte comparing
is coded as:
   if (...
  recordVersion.major > ProtocolVersion.MAX.major) {
  throw new SSLException
   }

"recordVersion.major" and "ProtocolVersion.MAX.major" is byte type,
which is signed.  If the major version is "0xa9", recordVersion.major is
a negative value (-87).  If ProtocolVersion.MAX.major is positive, the
checking above does not work any more.

This fix converts the version number to positive value before make the
comparing.

Thanks,
Xuelei


Re: [PATCH] Add class java.security.StandardMessageDigests

2014-05-06 Thread Florian Weimer

On 05/05/2014 04:43 PM, Xuelei Fan wrote:


It's 10% faster, even including the digest overhead for a single-block message.



clone() is an optional operation for MD. This point may make this class 
unreliable.


I think the MessageDigest specification requires that this works.  The 
TLS implementation also relies on this behavior (i.e. clone() either 
consistently fails or consistently succeeds).


Note that I'm not blindly calling clone(), I'm providing a fallback in 
case clone() does not work.



I think it might be a better place to make the improvement in crypto providers.


What kind of improvement are you thinking of?


BTW! I guess in some situation or some providers, clone() might not be a 
lightweight operation.


Hmm.  I can see that the state cannot be cloned at all (that's why 
cloning is optional), but allocating a new state has to happen anyway, 
no matter how the object is constructed.



I think the single-block hashing case is important because it is not always 
possible to reuse an existing digest object after calling reset().



It means the reset() does not work.   Looks like a bug to me.


What I meant is that there might be no place to store the reference to a 
long-term MessageDigest object which is reused again and again, so the 
best thing the code can do is to allocate a fresh object when it is needed?


Hmm, maybe we could provide a tread-local message digest that can be 
used to hash byte arrays?  It would address the simplest possible case 
where the instantiation overhead is most visible.


--
Florian Weimer / Red Hat Product Security Team