001: /*
002: * @(#)Certificate.java 1.25 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.security.cert;
029:
030: import java.util.Arrays;
031:
032: import java.security.PublicKey;
033: import java.security.NoSuchAlgorithmException;
034: import java.security.NoSuchProviderException;
035: import java.security.InvalidKeyException;
036: import java.security.SignatureException;
037:
038: import sun.security.x509.X509CertImpl;
039:
040: /**
041: * <p>Abstract class for managing a variety of identity certificates.
042: * An identity certificate is a binding of a principal to a public key which
043: * is vouched for by another principal. (A principal represents
044: * an entity such as an individual user, a group, or a corporation.)
045: *<p>
046: * This class is an abstraction for certificates that have different
047: * formats but important common uses. For example, different types of
048: * certificates, such as X.509 and PGP, share general certificate
049: * functionality (like encoding and verifying) and
050: * some types of information (like a public key).
051: * <p>
052: * X.509, PGP, and SDSI certificates can all be implemented by
053: * subclassing the Certificate class, even though they contain different
054: * sets of information, and they store and retrieve the information in
055: * different ways.
056: *
057: * @see X509Certificate
058: * @see CertificateFactory
059: *
060: * @author Hemma Prafullchandra
061: * @version 1.25, 10/10/06
062: */
063:
064: public abstract class Certificate implements java.io.Serializable {
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: * "../../../../guide/security/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: */
208: protected static class CertificateRep implements
209: java.io.Serializable {
210: private String type;
211: private byte[] data;
212:
213: /**
214: * Construct the alternate Certificate class with the Certificate
215: * type and Certificate encoding bytes.
216: *
217: * <p>
218: *
219: * @param type the standard name of the Certificate type. <p>
220: *
221: * @param data the Certificate data.
222: */
223: protected CertificateRep(String type, byte[] data) {
224: this .type = type;
225: this .data = data;
226: }
227:
228: /**
229: * Resolve the Certificate Object.
230: *
231: * <p>
232: *
233: * @return the resolved Certificate Object
234: *
235: * @throws java.io.ObjectStreamException if the Certificate
236: * could not be resolved
237: */
238: protected Object readResolve()
239: throws java.io.ObjectStreamException {
240: try {
241: CertificateFactory cf = CertificateFactory
242: .getInstance(type);
243: return cf
244: .generateCertificate(new java.io.ByteArrayInputStream(
245: data));
246: } catch (CertificateException e) {
247: throw new java.io.NotSerializableException(
248: "java.security.cert.Certificate: " + type
249: + ": " + e.getMessage());
250: }
251: }
252: }
253:
254: /**
255: * Replace the Certificate to be serialized.
256: *
257: * @return the alternate Certificate object to be serialized
258: *
259: * @throws java.io.ObjectStreamException if a new object representing
260: * this Certificate could not be created
261: */
262: protected Object writeReplace()
263: throws java.io.ObjectStreamException {
264: try {
265: return new CertificateRep(type, getEncoded());
266: } catch (CertificateException e) {
267: throw new java.io.NotSerializableException(
268: "java.security.cert.Certificate: " + type + ": "
269: + e.getMessage());
270: }
271: }
272: }
|