0N/A/*
2362N/A * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.timestamp;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.math.BigInteger;
0N/Aimport java.security.cert.X509Extension;
0N/Aimport sun.security.util.DerValue;
0N/Aimport sun.security.util.DerOutputStream;
0N/Aimport sun.security.util.ObjectIdentifier;
0N/A
0N/A/**
0N/A * This class provides a timestamp request, as defined in
0N/A * <a href="http://www.ietf.org/rfc/rfc3161.txt">RFC 3161</a>.
0N/A *
0N/A * The TimeStampReq ASN.1 type has the following definition:
0N/A * <pre>
0N/A *
0N/A * TimeStampReq ::= SEQUENCE {
0N/A * version INTEGER { v1(1) },
0N/A * messageImprint MessageImprint
0N/A * -- a hash algorithm OID and the hash value of the data to be
0N/A * -- time-stamped.
0N/A * reqPolicy TSAPolicyId OPTIONAL,
0N/A * nonce INTEGER OPTIONAL,
0N/A * certReq BOOLEAN DEFAULT FALSE,
0N/A * extensions [0] IMPLICIT Extensions OPTIONAL }
0N/A *
0N/A * MessageImprint ::= SEQUENCE {
0N/A * hashAlgorithm AlgorithmIdentifier,
0N/A * hashedMessage OCTET STRING }
0N/A *
0N/A * TSAPolicyId ::= OBJECT IDENTIFIER
0N/A *
0N/A * </pre>
0N/A *
0N/A * @since 1.5
0N/A * @author Vincent Ryan
0N/A * @see Timestamper
0N/A */
0N/A
0N/Apublic class TSRequest {
0N/A
0N/A private static final ObjectIdentifier SHA1_OID;
0N/A private static final ObjectIdentifier MD5_OID;
0N/A static {
0N/A ObjectIdentifier sha1 = null;
0N/A ObjectIdentifier md5 = null;
0N/A try {
0N/A sha1 = new ObjectIdentifier("1.3.14.3.2.26");
0N/A md5 = new ObjectIdentifier("1.2.840.113549.2.5");
0N/A } catch (IOException ioe) {
0N/A // should not happen
0N/A }
0N/A SHA1_OID = sha1;
0N/A MD5_OID = md5;
0N/A }
0N/A
0N/A private int version = 1;
0N/A
0N/A private ObjectIdentifier hashAlgorithmId = null;
0N/A
0N/A private byte[] hashValue;
0N/A
0N/A private String policyId = null;
0N/A
0N/A private BigInteger nonce = null;
0N/A
0N/A private boolean returnCertificate = false;
0N/A
0N/A private X509Extension[] extensions = null;
0N/A
0N/A /**
0N/A * Constructs a timestamp request for the supplied hash value..
0N/A *
0N/A * @param hashValue The hash value. This is the data to be timestamped.
0N/A * @param hashAlgorithm The name of the hash algorithm.
0N/A */
0N/A public TSRequest(byte[] hashValue, String hashAlgorithm) {
0N/A
0N/A // Check the common hash algorithms
0N/A if ("MD5".equalsIgnoreCase(hashAlgorithm)) {
0N/A hashAlgorithmId = MD5_OID;
0N/A // Check that the hash value matches the hash algorithm
0N/A assert hashValue.length == 16;
0N/A
0N/A } else if ("SHA-1".equalsIgnoreCase(hashAlgorithm) ||
0N/A "SHA".equalsIgnoreCase(hashAlgorithm) ||
0N/A "SHA1".equalsIgnoreCase(hashAlgorithm)) {
0N/A hashAlgorithmId = SHA1_OID;
0N/A // Check that the hash value matches the hash algorithm
0N/A assert hashValue.length == 20;
0N/A
0N/A }
0N/A // Clone the hash value
0N/A this.hashValue = new byte[hashValue.length];
0N/A System.arraycopy(hashValue, 0, this.hashValue, 0, hashValue.length);
0N/A }
0N/A
0N/A /**
0N/A * Sets the Time-Stamp Protocol version.
0N/A *
0N/A * @param version The TSP version.
0N/A */
0N/A public void setVersion(int version) {
0N/A this.version = version;
0N/A }
0N/A
0N/A /**
0N/A * Sets an object identifier for the Time-Stamp Protocol policy.
0N/A *
0N/A * @param version The policy object identifier.
0N/A */
0N/A public void setPolicyId(String policyId) {
0N/A this.policyId = policyId;
0N/A }
0N/A
0N/A /**
0N/A * Sets a nonce.
0N/A * A nonce is a single-use random number.
0N/A *
0N/A * @param nonce The nonce value.
0N/A */
0N/A public void setNonce(BigInteger nonce) {
0N/A this.nonce = nonce;
0N/A }
0N/A
0N/A /**
0N/A * Request that the TSA include its signing certificate in the response.
0N/A *
0N/A * @param returnCertificate True if the TSA should return its signing
0N/A * certificate. By default it is not returned.
0N/A */
0N/A public void requestCertificate(boolean returnCertificate) {
0N/A this.returnCertificate = returnCertificate;
0N/A }
0N/A
0N/A /**
0N/A * Sets the Time-Stamp Protocol extensions.
0N/A *
0N/A * @param extensions The protocol extensions.
0N/A */
0N/A public void setExtensions(X509Extension[] extensions) {
0N/A this.extensions = extensions;
0N/A }
0N/A
0N/A public byte[] encode() throws IOException {
0N/A
0N/A DerOutputStream request = new DerOutputStream();
0N/A
0N/A // encode version
0N/A request.putInteger(version);
0N/A
0N/A // encode messageImprint
0N/A DerOutputStream messageImprint = new DerOutputStream();
0N/A DerOutputStream hashAlgorithm = new DerOutputStream();
0N/A hashAlgorithm.putOID(hashAlgorithmId);
0N/A messageImprint.write(DerValue.tag_Sequence, hashAlgorithm);
0N/A messageImprint.putOctetString(hashValue);
0N/A request.write(DerValue.tag_Sequence, messageImprint);
0N/A
0N/A // encode optional elements
0N/A
0N/A if (policyId != null) {
0N/A request.putOID(new ObjectIdentifier(policyId));
0N/A }
0N/A if (nonce != null) {
0N/A request.putInteger(nonce);
0N/A }
0N/A if (returnCertificate) {
0N/A request.putBoolean(true);
0N/A }
0N/A
0N/A DerOutputStream out = new DerOutputStream();
0N/A out.write(DerValue.tag_Sequence, request);
0N/A return out.toByteArray();
0N/A }
0N/A}