      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.CertPath;
     30
     31 /**
     32  * This class encapsulates information about a code signer.
     33  * It is immutable.
     34  *
     35  * @since 1.5
     36  * @author Vincent Ryan
     37  */
     38
     39 public final class CodeSigner implements Serializable {
     40
     41     @java.io.Serial
     42     private static final long serialVersionUID = 6819288105193937581L;
     43
     44     /**
     45      * The signer's certificate path.
     46      *
     47      * @serial
     48      */
     49     private CertPath signerCertPath;
     50
     51     /*
     52      * The signature timestamp.
     53      *
     54      * @serial
     55      */
     56     private Timestamp timestamp;
     57
     58     /*
     59      * Hash code for this code signer.
     60      */
     61     private transient int myhash = -1;
     62
     63     /**
     64      * Constructs a CodeSigner object.
     65      *
     66      * @param signerCertPath The signer's certificate path.
     67      *                       It must not be {@code null}.
     68      * @param timestamp A signature timestamp.
     69      *                  If {@code null} then no timestamp was generated
     70      *                  for the signature.
     71      * @throws NullPointerException if {@code signerCertPath} is
     72      *                              {@code null}.
     73      */
     74     public CodeSigner(CertPath signerCertPath, Timestamp timestamp) {
     75         if (signerCertPath == null) {
     76             throw new NullPointerException();
     77         }
     78         this.signerCertPath = signerCertPath;
     79         this.timestamp = timestamp;
     80     }
     81
     82     /**
     83      * Returns the signer's certificate path.
     84      *
     85      * @return A certificate path.
     86      */
     87     public CertPath getSignerCertPath() {
     88         return signerCertPath;
     89     }
     90
     91     /**
     92      * Returns the signature timestamp.
     93      *
     94      * @return The timestamp or {@code null} if none is present.
     95      */
     96     public Timestamp getTimestamp() {
     97         return timestamp;
     98     }
     99
    100     /**
    101      * Returns the hash code value for this code signer.
    102      * The hash code is generated using the signer's certificate path and the
    103      * timestamp, if present.
    104      *
    105      * @return a hash code value for this code signer.
    106      */
    107     public int hashCode() {
    108         if (myhash == -1) {
    109             if (timestamp == null) {
    110                 myhash = signerCertPath.hashCode();
    111             } else {
    112                 myhash = signerCertPath.hashCode() + timestamp.hashCode();
    113             }
    114         }
    115         return myhash;
    116     }
    117
    118     /**
    119      * Tests for equality between the specified object and this
    120      * code signer. Two code signers are considered equal if their
    121      * signer certificate paths are equal and if their timestamps are equal,
    122      * if present in both.
    123      *
    124      * @param obj the object to test for equality with this object.
    125      *
    126      * @return true if the objects are considered equal, false otherwise.
    127      */
    128     public boolean equals(Object obj) {
    129         if (obj == null || (!(obj instanceof CodeSigner))) {
    130             return false;
    131         }
    132         CodeSigner that = (CodeSigner)obj;
    133
    134         if (this == that) {
    135             return true;
    136         }
    137         Timestamp thatTimestamp = that.getTimestamp();
    138         if (timestamp == null) {
    139             if (thatTimestamp != null) {
    140                 return false;
    141             }
    142         } else {
    143             if (thatTimestamp == null ||
    144                 (! timestamp.equals(thatTimestamp))) {
    145                 return false;
    146             }
    147         }
    148         return signerCertPath.equals(that.getSignerCertPath());
    149     }
    150
    151     /**
    152      * Returns a string describing this code signer.
    153      *
    154      * @return A string comprising the signer's certificate and a timestamp,
    155      *         if present.
    156      */
    157     public String toString() {
    158         StringBuilder sb = new StringBuilder();
    159         sb.append("(");
    160         sb.append("Signer: " + signerCertPath.getCertificates().get(0));
    161         if (timestamp != null) {
    162             sb.append("timestamp: " + timestamp);
    163         }
    164         sb.append(")");
    165         return sb.toString();
    166     }
    167
    168     // Explicitly reset hash code value to -1

    169     @java.io.Serial
    170     private void readObject(ObjectInputStream ois)
    171         throws IOException, ClassNotFoundException {
    172      ois.defaultReadObject();
    173      myhash = -1;
    174     }
    175 }
    --- EOF ---