001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Vladimir N. Molotkov
020: * @version $Revision$
021: */package java.security.cert;
022:
023: import java.io.ByteArrayInputStream;
024: import java.io.NotSerializableException;
025: import java.io.ObjectStreamException;
026: import java.io.ObjectStreamField;
027: import java.io.Serializable;
028: import java.security.InvalidKeyException;
029: import java.security.NoSuchAlgorithmException;
030: import java.security.NoSuchProviderException;
031: import java.security.PublicKey;
032: import java.security.SignatureException;
033: import java.util.Arrays;
034:
035: import org.apache.harmony.security.internal.nls.Messages;
036:
037: /**
038: * Abstract class to represent identity certificates. It represents a way to
039: * verify the binding of a Principal and its public key. Examples are X.509,
040: * PGP, and SDSI.
041: */
042: public abstract class Certificate implements Serializable {
043: /**
044: * @com.intel.drl.spec_ref
045: */
046: private static final long serialVersionUID = -3585440601605666277L;
047:
048: // The standard name of the certificate type
049: private final String type;
050:
051: /**
052: * @com.intel.drl.spec_ref
053: */
054: protected Certificate(String type) {
055: this .type = type;
056: }
057:
058: /**
059: * Answers the certificate type represented by the receiver.
060: *
061: * @return the certificate type represented by the receiver.
062: */
063: public final String getType() {
064: return type;
065: }
066:
067: /**
068: * Compares the argument to the receiver, and answers true if they represent
069: * the <em>same</em> object using a class specific comparison. The
070: * implementation in Object answers true only if the argument is the exact
071: * same object as the receiver (==).
072: *
073: * @param other
074: * the object to compare with this object
075: * @return <code>true</code> if the object is the same as this object
076: * <code>false</code> if it is different from this object
077: * @see #hashCode
078: */
079: public boolean equals(Object other) {
080: // obj equal to itself
081: if (this == other) {
082: return true;
083: }
084: if (other instanceof Certificate) {
085: try {
086: // check that encoded forms match
087: return Arrays.equals(this .getEncoded(),
088: ((Certificate) other).getEncoded());
089: } catch (CertificateEncodingException e) {
090: throw new RuntimeException(e);
091: }
092: }
093: return false;
094: }
095:
096: /**
097: * Answers an integer hash code for the receiver. Any two objects which
098: * answer <code>true</code> when passed to <code>equals</code> must
099: * answer the same value for this method.
100: *
101: * @return the receiver's hash
102: *
103: * @see #equals
104: */
105: public int hashCode() {
106: try {
107: byte[] encoded = getEncoded();
108: int hash = 0;
109: for (int i = 0; i < encoded.length; i++) {
110: hash += i * encoded[i];
111: }
112: return hash;
113: } catch (CertificateEncodingException e) {
114: throw new RuntimeException(e);
115: }
116: }
117:
118: /**
119: * Answers the encoded representation for this certificate.
120: *
121: * @return the encoded representation for this certificate.
122: */
123: public abstract byte[] getEncoded()
124: throws CertificateEncodingException;
125:
126: /**
127: * Verifies that this certificate was signed with the given public key.
128: *
129: * @param key
130: * PublicKey public key for which verification should be
131: * performed.
132: *
133: * @exception CertificateException
134: * if encoding errors are detected
135: * @exception NoSuchAlgorithmException
136: * if an unsupported algorithm is detected
137: * @exception InvalidKeyException
138: * if an invalid key is detected
139: * @exception NoSuchProviderException
140: * if there is no default provider
141: * @exception SignatureException
142: * if signature errors are detected
143: */
144: public abstract void verify(PublicKey key)
145: throws CertificateException, NoSuchAlgorithmException,
146: InvalidKeyException, NoSuchProviderException,
147: SignatureException;
148:
149: /**
150: * Verifies that this certificate was signed with the given public key. Uses
151: * the signature algorithm given by the provider.
152: *
153: * @param key
154: * PublicKey public key for which verification should be
155: * performed.
156: * @param sigProvider
157: * String the name of the signature provider.
158: *
159: * @exception CertificateException
160: * if encoding errors are detected
161: * @exception NoSuchAlgorithmException
162: * if an unsupported algorithm is detected
163: * @exception InvalidKeyException
164: * if an invalid key is detected
165: * @exception NoSuchProviderException
166: * if there is no default provider
167: * @exception SignatureException
168: * if signature errors are detected
169: */
170: public abstract void verify(PublicKey key, String sigProvider)
171: throws CertificateException, NoSuchAlgorithmException,
172: InvalidKeyException, NoSuchProviderException,
173: SignatureException;
174:
175: /**
176: * Answers a string containing a concise, human-readable description of the
177: * receiver.
178: *
179: * @return a printable representation for the receiver.
180: */
181: public abstract String toString();
182:
183: /**
184: * Answers the public key corresponding to this certificate.
185: *
186: * @return the public key corresponding to this certificate.
187: */
188: public abstract PublicKey getPublicKey();
189:
190: /**
191: * @com.intel.drl.spec_ref
192: */
193: protected Object writeReplace() throws ObjectStreamException {
194: try {
195: return new CertificateRep(getType(), getEncoded());
196: } catch (CertificateEncodingException e) {
197: throw new NotSerializableException(Messages.getString(
198: "security.66", e)); //$NON-NLS-1$
199: }
200: }
201:
202: /**
203: * @com.intel.drl.spec_ref
204: *
205: */
206: protected static class CertificateRep implements Serializable {
207: /**
208: * @com.intel.drl.spec_ref
209: */
210: private static final long serialVersionUID = -8563758940495660020L;
211: // The standard name of the certificate type
212: private final String type;
213: // The certificate data
214: private final byte[] data;
215:
216: // Force default serialization to use writeUnshared/readUnshared
217: // for the certificate data
218: private static final ObjectStreamField[] serialPersistentFields = {
219: new ObjectStreamField("type", String.class), //$NON-NLS-1$
220: new ObjectStreamField("data", byte[].class, true) //$NON-NLS-1$
221: };
222:
223: /**
224: * @com.intel.drl.spec_ref
225: */
226: protected CertificateRep(String type, byte[] data) {
227: this .type = type;
228: this .data = data;
229: }
230:
231: /**
232: * @com.intel.drl.spec_ref
233: */
234: protected Object readResolve() throws ObjectStreamException {
235: try {
236: CertificateFactory cf = CertificateFactory
237: .getInstance(type);
238: return cf.generateCertificate(new ByteArrayInputStream(
239: data));
240: } catch (Throwable t) {
241: throw new NotSerializableException(Messages.getString(
242: "security.68", t)); //$NON-NLS-1$
243: }
244: }
245: }
246: }
|