CodeSigner.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security;
19
20import java.io.Serializable;
21import java.security.cert.CertPath;
22
23import org.apache.harmony.security.internal.nls.Messages;
24
25/**
26 * {@code CodeSigner} represents a signer of code. Instances are immutable.
27 */
28public final class CodeSigner implements Serializable {
29
30    private static final long serialVersionUID = 6819288105193937581L;
31
32    private CertPath signerCertPath;
33
34    private Timestamp timestamp;
35
36    // Cached hash code value
37    private transient int hash;
38
39    /**
40     * Constructs a new instance of {@code CodeSigner}.
41     *
42     * @param signerCertPath
43     *            the certificate path associated with this code signer.
44     * @param timestamp
45     *            the time stamp associated with this code signer, maybe {@code
46     *            null}.
47     * @throws NullPointerException
48     *             if {@code signerCertPath} is {@code null}.
49     */
50    public CodeSigner(CertPath signerCertPath, Timestamp timestamp) {
51        if (signerCertPath == null) {
52            throw new NullPointerException(Messages.getString("security.10"));
53        }
54        this.signerCertPath = signerCertPath;
55        this.timestamp = timestamp;
56    }
57
58    /**
59     * Compares the specified object with this {@code CodeSigner} for equality.
60     * Returns {@code true} if the specified object is also an instance of
61     * {@code CodeSigner}, the two {@code CodeSigner} encapsulate the same
62     * certificate path and the same time stamp, if present in both.
63     *
64     * @param obj
65     *            object to be compared for equality with this {@code
66     *            CodeSigner}.
67     * @return {@code true} if the specified object is equal to this {@code
68     *         CodeSigner}, otherwise {@code false}.
69     */
70    @Override
71    public boolean equals(Object obj) {
72        if (obj == this) {
73            return true;
74        }
75        if (obj instanceof CodeSigner) {
76            CodeSigner that = (CodeSigner) obj;
77            if (!signerCertPath.equals(that.signerCertPath)) {
78                return false;
79            }
80            return timestamp == null ? that.timestamp == null : timestamp
81                    .equals(that.timestamp);
82        }
83        return false;
84    }
85
86    /**
87     * Returns the certificate path associated with this {@code CodeSigner}.
88     *
89     * @return the certificate path associated with this {@code CodeSigner}.
90     */
91    public CertPath getSignerCertPath() {
92        return signerCertPath;
93    }
94
95    /**
96     * Returns the time stamp associated with this {@code CodeSigner}.
97     *
98     * @return the time stamp associated with this {@code CodeSigner}, maybe
99     *         {@code null}.
100     */
101    public Timestamp getTimestamp() {
102        return timestamp;
103    }
104
105    /**
106     * Returns the hash code value for this {@code CodeSigner}. Returns the same
107     * hash code for {@code CodeSigner}s that are equal to each other as
108     * required by the general contract of {@link Object#hashCode}.
109     *
110     * @return the hash code value for this {@code CodeSigner}.
111     * @see Object#equals(Object)
112     * @see CodeSigner#equals(Object)
113     */
114    @Override
115    public int hashCode() {
116        if (hash == 0) {
117            hash = signerCertPath.hashCode()
118                    ^ (timestamp == null ? 0 : timestamp.hashCode());
119        }
120        return hash;
121    }
122
123    /**
124     * Returns a string containing a concise, human-readable description of the
125     * this {@code CodeSigner} including its first certificate and its time
126     * stamp, if present.
127     *
128     * @return a printable representation for this {@code CodeSigner}.
129     */
130    @Override
131    public String toString() {
132        // There is no any special reason for '256' here, it's taken abruptly
133        StringBuilder buf = new StringBuilder(256);
134        // The javadoc says nothing, and the others implementations behavior seems as
135        // dumping only the first certificate. Well, let's do the same.
136        buf.append("CodeSigner [").append(signerCertPath.getCertificates().get(0));
137        if( timestamp != null ) {
138            buf.append("; ").append(timestamp);
139        }
140        buf.append("]");
141        return buf.toString();
142    }
143}
144