J2SE Version (please include all output from java -version flag):
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
Does this problem occur on J2SE 1.3, 1.4.x or 1.5? Yes / No (pick one)
Not tested.
Operating System Configuration Information (be specific):
Windows Server 2003 SP 2
Hardware Configuration Information (be specific):
Toshiba Tecra S5
Bug Description:
The JARSigner does not correctly interpret failure information of a trusted timestamp service.
According to RFC 3161 (cf. http://www.ietf.org/rfc/rfc3161.txt), the optional field failinfo is defined as:
PKIStatusInfo ::= SEQUENCE {
status PKIStatus,
statusString PKIFreeText OPTIONAL,
failInfo PKIFailureInfo OPTIONAL }
Although optional, there are situations, where sending this field is strongly recommended. The RFC says:
When the TimeStampToken is not present, the failInfo indicates the
reason why the time-stamp request was rejected and may be one of the
following values. [¿
E.g.:
... if an extension, whether it is marked critical or not critical, is
used by a requester but is not recognized by a time-stamping server,
the server SHALL not issue a token and SHALL return a failure
(unacceptedExtension).
Note that PKIFailureInfo is defined as a DER bit string.
PKIFailureInfo ::= BIT STRING {
badAlg (0),
-- unrecognized or unsupported Algorithm Identifier
badRequest (2),
-- transaction not permitted or supported
[...]
}
E.g. the exception ¿adRequest¿ (error code 2) implies that the bit mit index 2 is set. The bit string value would be 00100000 in that case (the set bit followed by 5 padding bits).
JarSigner, however, does the following (cf. class sun.security.timestamp.TSResponse, method
private void parse(byte[] tsReply) throws IOException)
Code-snippet:
if (status.data.available() > 0)
{
byte[] failInfo = status.data.getBitString();
int failureInfo = (new Byte(failInfo[0])).intValue();
if (failureInfo < 0 || failureInfo > 25 || failInfo.length != 1)
{
throw new IOException("Bad encoding for timestamp response: "
+ "unrecognized value for the failInfo element");
}
this.failureInfo = failureInfo;
}
That means that JarSigner converts the bit string to a byte array and inteprets the individual bytes on a binary basis. Consequently, the badRequest example code evaluates to 32, which is incorrect and results in an exception being thrown.
Cf. the X.690 specification for more details concerning the interpreation of DER bit strings:
http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
Steps to Reproduce (be specific):
Use the JARSigner with a correctly working timestamp server supplying failure informantion and try to generate an error condition.