|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.timestamp; |
|
|
|
import java.io.IOException; |
|
import java.math.BigInteger; |
|
import java.util.Date; |
|
import sun.security.util.DerValue; |
|
import sun.security.util.ObjectIdentifier; |
|
import sun.security.x509.AlgorithmId; |
|
|
|
/** |
|
* This class provides the timestamp token info resulting from a successful |
|
* timestamp request, as defined in |
|
* <a href="http://www.ietf.org/rfc/rfc3161.txt">RFC 3161</a>. |
|
* |
|
* The timestampTokenInfo ASN.1 type has the following definition: |
|
* <pre> |
|
* |
|
* TSTInfo ::= SEQUENCE { |
|
* version INTEGER { v1(1) }, |
|
* policy TSAPolicyId, |
|
* messageImprint MessageImprint, |
|
* -- MUST have the same value as the similar field in |
|
* -- TimeStampReq |
|
* serialNumber INTEGER, |
|
* -- Time-Stamping users MUST be ready to accommodate integers |
|
* -- up to 160 bits. |
|
* genTime GeneralizedTime, |
|
* accuracy Accuracy OPTIONAL, |
|
* ordering BOOLEAN DEFAULT FALSE, |
|
* nonce INTEGER OPTIONAL, |
|
* -- MUST be present if the similar field was present |
|
* -- in TimeStampReq. In that case it MUST have the same value. |
|
* tsa [0] GeneralName OPTIONAL, |
|
* extensions [1] IMPLICIT Extensions OPTIONAL } |
|
* |
|
* Accuracy ::= SEQUENCE { |
|
* seconds INTEGER OPTIONAL, |
|
* millis [0] INTEGER (1..999) OPTIONAL, |
|
* micros [1] INTEGER (1..999) OPTIONAL } |
|
* |
|
* </pre> |
|
* |
|
* @since 1.5 |
|
* @see Timestamper |
|
* @author Vincent Ryan |
|
*/ |
|
|
|
public class TimestampToken { |
|
|
|
private int version; |
|
private ObjectIdentifier policy; |
|
private BigInteger serialNumber; |
|
private AlgorithmId hashAlgorithm; |
|
private byte[] hashedMessage; |
|
private Date genTime; |
|
private BigInteger nonce; |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public TimestampToken(byte[] timestampTokenInfo) throws IOException { |
|
if (timestampTokenInfo == null) { |
|
throw new IOException("No timestamp token info"); |
|
} |
|
parse(timestampTokenInfo); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Date getDate() { |
|
return genTime; |
|
} |
|
|
|
public AlgorithmId getHashAlgorithm() { |
|
return hashAlgorithm; |
|
} |
|
|
|
|
|
public byte[] getHashedMessage() { |
|
return hashedMessage; |
|
} |
|
|
|
public BigInteger getNonce() { |
|
return nonce; |
|
} |
|
|
|
public String getPolicyID() { |
|
return policy.toString(); |
|
} |
|
|
|
public BigInteger getSerialNumber() { |
|
return serialNumber; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private void parse(byte[] timestampTokenInfo) throws IOException { |
|
|
|
DerValue tstInfo = new DerValue(timestampTokenInfo); |
|
if (tstInfo.tag != DerValue.tag_Sequence) { |
|
throw new IOException("Bad encoding for timestamp token info"); |
|
} |
|
|
|
version = tstInfo.data.getInteger(); |
|
|
|
|
|
policy = tstInfo.data.getOID(); |
|
|
|
|
|
DerValue messageImprint = tstInfo.data.getDerValue(); |
|
hashAlgorithm = AlgorithmId.parse(messageImprint.data.getDerValue()); |
|
hashedMessage = messageImprint.data.getOctetString(); |
|
|
|
|
|
serialNumber = tstInfo.data.getBigInteger(); |
|
|
|
|
|
genTime = tstInfo.data.getGeneralizedTime(); |
|
|
|
|
|
while (tstInfo.data.available() > 0) { |
|
DerValue d = tstInfo.data.getDerValue(); |
|
if (d.tag == DerValue.tag_Integer) { |
|
nonce = d.getBigInteger(); |
|
break; |
|
} |
|
|
|
// Additional fields: |
|
// Parse accuracy |
|
// Parse ordering |
|
// Parse tsa |
|
// Parse extensions |
|
} |
|
} |
|
} |