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 23/** 24 * {@code CodeSigner} represents a signer of code. Instances are immutable. 25 */ 26public final class CodeSigner implements Serializable { 27 28 private static final long serialVersionUID = 6819288105193937581L; 29 30 private CertPath signerCertPath; 31 32 private Timestamp timestamp; 33 34 // Cached hash code value 35 private transient int hash; 36 37 /** 38 * Constructs a new instance of {@code CodeSigner}. 39 * 40 * @param signerCertPath 41 * the certificate path associated with this code signer. 42 * @param timestamp 43 * the time stamp associated with this code signer, maybe {@code 44 * null}. 45 * @throws NullPointerException 46 * if {@code signerCertPath} is {@code null}. 47 */ 48 public CodeSigner(CertPath signerCertPath, Timestamp timestamp) { 49 if (signerCertPath == null) { 50 throw new NullPointerException("signerCertPath == null"); 51 } 52 this.signerCertPath = signerCertPath; 53 this.timestamp = timestamp; 54 } 55 56 /** 57 * Compares the specified object with this {@code CodeSigner} for equality. 58 * Returns {@code true} if the specified object is also an instance of 59 * {@code CodeSigner}, the two {@code CodeSigner} encapsulate the same 60 * certificate path and the same time stamp, if present in both. 61 * 62 * @param obj 63 * object to be compared for equality with this {@code 64 * CodeSigner}. 65 * @return {@code true} if the specified object is equal to this {@code 66 * CodeSigner}, otherwise {@code false}. 67 */ 68 @Override 69 public boolean equals(Object obj) { 70 if (obj == this) { 71 return true; 72 } 73 if (obj instanceof CodeSigner) { 74 CodeSigner that = (CodeSigner) obj; 75 if (!signerCertPath.equals(that.signerCertPath)) { 76 return false; 77 } 78 return timestamp == null ? that.timestamp == null : timestamp 79 .equals(that.timestamp); 80 } 81 return false; 82 } 83 84 /** 85 * Returns the certificate path associated with this {@code CodeSigner}. 86 * 87 * @return the certificate path associated with this {@code CodeSigner}. 88 */ 89 public CertPath getSignerCertPath() { 90 return signerCertPath; 91 } 92 93 /** 94 * Returns the time stamp associated with this {@code CodeSigner}. 95 * 96 * @return the time stamp associated with this {@code CodeSigner}, maybe 97 * {@code null}. 98 */ 99 public Timestamp getTimestamp() { 100 return timestamp; 101 } 102 103 /** 104 * Returns the hash code value for this {@code CodeSigner}. Returns the same 105 * hash code for {@code CodeSigner}s that are equal to each other as 106 * required by the general contract of {@link Object#hashCode}. 107 * 108 * @return the hash code value for this {@code CodeSigner}. 109 * @see Object#equals(Object) 110 * @see CodeSigner#equals(Object) 111 */ 112 @Override 113 public int hashCode() { 114 if (hash == 0) { 115 hash = signerCertPath.hashCode() 116 ^ (timestamp == null ? 0 : timestamp.hashCode()); 117 } 118 return hash; 119 } 120 121 /** 122 * Returns a string containing a concise, human-readable description of the 123 * this {@code CodeSigner} including its first certificate and its time 124 * stamp, if present. 125 * 126 * @return a printable representation for this {@code CodeSigner}. 127 */ 128 @Override 129 public String toString() { 130 // There is no any special reason for '256' here, it's taken abruptly 131 StringBuilder buf = new StringBuilder(256); 132 // The javadoc says nothing, and the others implementations behavior seems as 133 // dumping only the first certificate. Well, let's do the same. 134 buf.append("CodeSigner [").append(signerCertPath.getCertificates().get(0)); 135 if( timestamp != null ) { 136 buf.append("; ").append(timestamp); 137 } 138 buf.append("]"); 139 return buf.toString(); 140 } 141} 142