001 /*
002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.security.cert;
027
028 import java.util.Arrays;
029
030 import java.security.PublicKey;
031 import java.security.NoSuchAlgorithmException;
032 import java.security.NoSuchProviderException;
033 import java.security.InvalidKeyException;
034 import java.security.SignatureException;
035
036 import sun.security.x509.X509CertImpl;
037
038 /**
039 * <p>Abstract class for managing a variety of identity certificates.
040 * An identity certificate is a binding of a principal to a public key which
041 * is vouched for by another principal. (A principal represents
042 * an entity such as an individual user, a group, or a corporation.)
043 *<p>
044 * This class is an abstraction for certificates that have different
045 * formats but important common uses. For example, different types of
046 * certificates, such as X.509 and PGP, share general certificate
047 * functionality (like encoding and verifying) and
048 * some types of information (like a public key).
049 * <p>
050 * X.509, PGP, and SDSI certificates can all be implemented by
051 * subclassing the Certificate class, even though they contain different
052 * sets of information, and they store and retrieve the information in
053 * different ways.
054 *
055 * @see X509Certificate
056 * @see CertificateFactory
057 *
058 * @author Hemma Prafullchandra
059 * @version 1.33, 05/05/07
060 */
061
062 public abstract class Certificate implements java.io.Serializable {
063
064 private static final long serialVersionUID = -3585440601605666277L;
065
066 // the certificate type
067 private final String type;
068
069 /**
070 * Creates a certificate of the specified type.
071 *
072 * @param type the standard name of the certificate type.
073 * See Appendix A in the <a href=
074 * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
075 * Java Cryptography Architecture API Specification & Reference </a>
076 * for information about standard certificate types.
077 */
078 protected Certificate(String type) {
079 this .type = type;
080 }
081
082 /**
083 * Returns the type of this certificate.
084 *
085 * @return the type of this certificate.
086 */
087 public final String getType() {
088 return this .type;
089 }
090
091 /**
092 * Compares this certificate for equality with the specified
093 * object. If the <code>other</code> object is an
094 * <code>instanceof</code> <code>Certificate</code>, then
095 * its encoded form is retrieved and compared with the
096 * encoded form of this certificate.
097 *
098 * @param other the object to test for equality with this certificate.
099 * @return true iff the encoded forms of the two certificates
100 * match, false otherwise.
101 */
102 public boolean equals(Object other) {
103 if (this == other) {
104 return true;
105 }
106 if (!(other instanceof Certificate)) {
107 return false;
108 }
109 try {
110 byte[] this Cert = X509CertImpl.getEncodedInternal(this );
111 byte[] otherCert = X509CertImpl
112 .getEncodedInternal((Certificate) other);
113
114 return Arrays.equals(this Cert, otherCert);
115 } catch (CertificateException e) {
116 return false;
117 }
118 }
119
120 /**
121 * Returns a hashcode value for this certificate from its
122 * encoded form.
123 *
124 * @return the hashcode value.
125 */
126 public int hashCode() {
127 int retval = 0;
128 try {
129 byte[] certData = X509CertImpl.getEncodedInternal(this );
130 for (int i = 1; i < certData.length; i++) {
131 retval += certData[i] * i;
132 }
133 return retval;
134 } catch (CertificateException e) {
135 return retval;
136 }
137 }
138
139 /**
140 * Returns the encoded form of this certificate. It is
141 * assumed that each certificate type would have only a single
142 * form of encoding; for example, X.509 certificates would
143 * be encoded as ASN.1 DER.
144 *
145 * @return the encoded form of this certificate
146 *
147 * @exception CertificateEncodingException if an encoding error occurs.
148 */
149 public abstract byte[] getEncoded()
150 throws CertificateEncodingException;
151
152 /**
153 * Verifies that this certificate was signed using the
154 * private key that corresponds to the specified public key.
155 *
156 * @param key the PublicKey used to carry out the verification.
157 *
158 * @exception NoSuchAlgorithmException on unsupported signature
159 * algorithms.
160 * @exception InvalidKeyException on incorrect key.
161 * @exception NoSuchProviderException if there's no default provider.
162 * @exception SignatureException on signature errors.
163 * @exception CertificateException on encoding errors.
164 */
165 public abstract void verify(PublicKey key)
166 throws CertificateException, NoSuchAlgorithmException,
167 InvalidKeyException, NoSuchProviderException,
168 SignatureException;
169
170 /**
171 * Verifies that this certificate was signed using the
172 * private key that corresponds to the specified public key.
173 * This method uses the signature verification engine
174 * supplied by the specified provider.
175 *
176 * @param key the PublicKey used to carry out the verification.
177 * @param sigProvider the name of the signature provider.
178 *
179 * @exception NoSuchAlgorithmException on unsupported signature
180 * algorithms.
181 * @exception InvalidKeyException on incorrect key.
182 * @exception NoSuchProviderException on incorrect provider.
183 * @exception SignatureException on signature errors.
184 * @exception CertificateException on encoding errors.
185 */
186 public abstract void verify(PublicKey key, String sigProvider)
187 throws CertificateException, NoSuchAlgorithmException,
188 InvalidKeyException, NoSuchProviderException,
189 SignatureException;
190
191 /**
192 * Returns a string representation of this certificate.
193 *
194 * @return a string representation of this certificate.
195 */
196 public abstract String toString();
197
198 /**
199 * Gets the public key from this certificate.
200 *
201 * @return the public key.
202 */
203 public abstract PublicKey getPublicKey();
204
205 /**
206 * Alternate Certificate class for serialization.
207 * @since 1.3
208 */
209 protected static class CertificateRep implements
210 java.io.Serializable {
211
212 private static final long serialVersionUID = -8563758940495660020L;
213
214 private String type;
215 private byte[] data;
216
217 /**
218 * Construct the alternate Certificate class with the Certificate
219 * type and Certificate encoding bytes.
220 *
221 * <p>
222 *
223 * @param type the standard name of the Certificate type. <p>
224 *
225 * @param data the Certificate data.
226 */
227 protected CertificateRep(String type, byte[] data) {
228 this .type = type;
229 this .data = data;
230 }
231
232 /**
233 * Resolve the Certificate Object.
234 *
235 * <p>
236 *
237 * @return the resolved Certificate Object
238 *
239 * @throws java.io.ObjectStreamException if the Certificate
240 * could not be resolved
241 */
242 protected Object readResolve()
243 throws java.io.ObjectStreamException {
244 try {
245 CertificateFactory cf = CertificateFactory
246 .getInstance(type);
247 return cf
248 .generateCertificate(new java.io.ByteArrayInputStream(
249 data));
250 } catch (CertificateException e) {
251 throw new java.io.NotSerializableException(
252 "java.security.cert.Certificate: " + type
253 + ": " + e.getMessage());
254 }
255 }
256 }
257
258 /**
259 * Replace the Certificate to be serialized.
260 *
261 * @return the alternate Certificate object to be serialized
262 *
263 * @throws java.io.ObjectStreamException if a new object representing
264 * this Certificate could not be created
265 * @since 1.3
266 */
267 protected Object writeReplace()
268 throws java.io.ObjectStreamException {
269 try {
270 return new CertificateRep(type, getEncoded());
271 } catch (CertificateException e) {
272 throw new java.io.NotSerializableException(
273 "java.security.cert.Certificate: " + type + ": "
274 + e.getMessage());
275 }
276 }
277 }
|