      1 /*
      2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25
     26 package java.security;
     27
     28 import java.io.*;
     29 import java.security.cert.Certificate;
     30 import java.security.cert.CertPath;
     31 import java.security.cert.X509Extension;
     32 import java.util.Date;
     33 import java.util.List;
     34
     35 /**
     36  * This class encapsulates information about a signed timestamp.
     37  * It is immutable.
     38  * It includes the timestamp's date and time as well as information about the
     39  * Timestamping Authority (TSA) which generated and signed the timestamp.
     40  *
     41  * @since 1.5
     42  * @author Vincent Ryan
     43  */
     44
     45 public final class Timestamp implements Serializable {
     46
     47     @java.io.Serial
     48     private static final long serialVersionUID = -5502683707821851294L;
     49
     50     /**
     51      * The timestamp's date and time
     52      *
     53      * @serial
     54      */
     55     private Date timestamp;
     56
     57     /**
     58      * The TSA's certificate path.
     59      *
     60      * @serial
     61      */
     62     private CertPath signerCertPath;
     63
     64     /*
     65      * Hash code for this timestamp.
     66      */
     67     private transient int myhash = -1;
     68
     69     /**
     70      * Constructs a Timestamp.
     71      *
     72      * @param timestamp is the timestamp's date and time. It must not be null.
     73      * @param signerCertPath is the TSA's certificate path. It must not be null.
     74      * @throws NullPointerException if timestamp or signerCertPath is null.
     75      */
     76     public Timestamp(Date timestamp, CertPath signerCertPath) {
     77         if (timestamp == null || signerCertPath == null) {
     78             throw new NullPointerException();
     79         }
     80         this.timestamp = new Date(timestamp.getTime()); // clone
     81         this.signerCertPath = signerCertPath;
     82     }
     83
     84     /**
     85      * Returns the date and time when the timestamp was generated.
     86      *
     87      * @return The timestamp's date and time.
     88      */
     89     public Date getTimestamp() {
     90         return new Date(timestamp.getTime()); // clone
     91     }
     92
     93     /**
     94      * Returns the certificate path for the Timestamping Authority.
     95      *
     96      * @return The TSA's certificate path.
     97      */
     98     public CertPath getSignerCertPath() {
     99         return signerCertPath;
    100     }
    101
    102     /**
    103      * Returns the hash code value for this timestamp.
    104      * The hash code is generated using the date and time of the timestamp
    105      * and the TSA's certificate path.
    106      *
    107      * @return a hash code value for this timestamp.
    108      */
    109     public int hashCode() {
    110         if (myhash == -1) {
    111             myhash = timestamp.hashCode() + signerCertPath.hashCode();
    112         }
    113         return myhash;
    114     }
    115
    116     /**
    117      * Tests for equality between the specified object and this
    118      * timestamp. Two timestamps are considered equal if the date and time of
    119      * their timestamp's and their signer's certificate paths are equal.
    120      *
    121      * @param obj the object to test for equality with this timestamp.
    122      *
    123      * @return true if the timestamp are considered equal, false otherwise.
    124      */
    125     public boolean equals(Object obj) {
    126         if (obj == null || (!(obj instanceof Timestamp))) {
    127             return false;
    128         }
    129         Timestamp that = (Timestamp)obj;
    130
    131         if (this == that) {
    132             return true;
    133         }
    134         return (timestamp.equals(that.getTimestamp()) &&
    135             signerCertPath.equals(that.getSignerCertPath()));
    136     }
    137
    138     /**
    139      * Returns a string describing this timestamp.
    140      *
    141      * @return A string comprising the date and time of the timestamp and
    142      *         its signer's certificate.
    143      */
    144     public String toString() {
    145         StringBuilder sb = new StringBuilder();
    146         sb.append("(");
    147         sb.append("timestamp: " + timestamp);
    148         List<? extends Certificate> certs = signerCertPath.getCertificates();
    149         if (!certs.isEmpty()) {
    150             sb.append("TSA: " + certs.get(0));
    151         } else {
    152             sb.append("TSA: <empty>");
    153         }
    154         sb.append(")");
    155         return sb.toString();
    156     }
    157
    158     // Explicitly reset hash code value to -1

    159     @java.io.Serial
    160     private void readObject(ObjectInputStream ois)
    161         throws IOException, ClassNotFoundException {
    162         ois.defaultReadObject();
    163         myhash = -1;
    164         timestamp = new Date(timestamp.getTime());
    165     }
    166 }
    --- EOF ---