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.util.Iterator;
029: import java.util.List;
030:
031: import org.apache.harmony.security.internal.nls.Messages;
032:
033: /**
034: * An immutable certificate path that can be validated. All certificates in the
035: * path are of the same type (i.e., X509).
036: *
037: * A <code>CertPath</code> can be represented as a byte array in at least one
038: * supported encoding when serialized.
039: *
040: * When a <code>List</code> of the certificates is obtained it must be
041: * immutable.
042: *
043: * A <code>CertPath</code> must be thread-safe without requiring coordinated
044: * access.
045: */
046: public abstract class CertPath implements Serializable {
047: /**
048: * @com.intel.drl.spec_ref
049: */
050: private static final long serialVersionUID = 6068470306649138683L;
051: // Standard name of the type of certificates in this path
052: private final String type;
053:
054: /**
055: * @com.intel.drl.spec_ref
056: */
057: protected CertPath(String type) {
058: this .type = type;
059: }
060:
061: /**
062: * Returns the type of <code>Certificate</code> in the
063: * <code>CertPath</code>
064: *
065: * @return <code>Certificate</code> type
066: */
067: public String getType() {
068: return type;
069: }
070:
071: /**
072: * Returns true if <code>Certificate</code>s in the list are the same
073: * type and the lists are equal (and by implication the certificates
074: * contained within are the same).
075: *
076: * @param other
077: * <code>CertPath</code> to be compared for equality
078: */
079: public boolean equals(Object other) {
080: if (this == other) {
081: return true;
082: }
083: if (other instanceof CertPath) {
084: CertPath o = (CertPath) other;
085: if (getType().equals(o.getType())) {
086: if (getCertificates().equals(o.getCertificates())) {
087: return true;
088: }
089: }
090: }
091: return false;
092: }
093:
094: /**
095: * Overrides Object.hashCode() Defined as: hashCode = 31 *
096: * path.getType().hashCode() + path.getCertificates().hashCode();
097: *
098: * @return hash code for CertPath object
099: */
100: public int hashCode() {
101: int hash = getType().hashCode();
102: hash = hash * 31 + getCertificates().hashCode();
103: return hash;
104: }
105:
106: /**
107: * Returns a <code>String</code> representation of the
108: * <code>CertPath</code>
109: * <code>Certificate</code>s. It is the result of
110: * calling <code>toString</code> on all <code>Certificate</code>s in
111: * the <code>List</code>. <code>Certificate</code>s
112: *
113: * @return string representation of <code>CertPath</code>
114: */
115: public String toString() {
116: StringBuffer sb = new StringBuffer(getType());
117: sb.append(" Cert Path, len="); //$NON-NLS-1$
118: sb.append(getCertificates().size());
119: sb.append(": [\n"); //$NON-NLS-1$
120: int n = 1;
121: for (Iterator i = getCertificates().iterator(); i.hasNext(); n++) {
122: sb.append("---------------certificate "); //$NON-NLS-1$
123: sb.append(n);
124: sb.append("---------------\n"); //$NON-NLS-1$
125: sb.append(((Certificate) i.next()).toString());
126: }
127: sb.append("\n]"); //$NON-NLS-1$
128: return sb.toString();
129: }
130:
131: /**
132: * Returns an immutable List of the <code>Certificate</code>s contained
133: * in the <code>CertPath</code>.
134: *
135: * @return list of <code>Certificate</code>s in the <code>CertPath</code>
136: */
137: public abstract List<? extends Certificate> getCertificates();
138:
139: /**
140: * Returns an encoding of the <code>CertPath</code> using the default
141: * encoding
142: *
143: * @return default encoding of the <code>CertPath</code>
144: * @throws CertificateEncodingException
145: */
146: public abstract byte[] getEncoded()
147: throws CertificateEncodingException;
148:
149: /**
150: * Returns an encoding of the <code>CertPath</code> using the specified
151: * encoding
152: *
153: * @param encoding
154: * encoding that should be generated
155: * @return default encoding of the <code>CertPath</code>
156: * @throws CertificateEncodingException
157: */
158: public abstract byte[] getEncoded(String encoding)
159: throws CertificateEncodingException;
160:
161: /**
162: * Return an <code>Iterator</code> over the supported encodings for a
163: * representation of the certificate path.
164: *
165: * @return <code>Iterator</code> over supported encodings (as
166: * <code>String</code>s)
167: */
168: public abstract Iterator<String> getEncodings();
169:
170: /**
171: * @com.intel.drl.spec_ref
172: */
173: protected Object writeReplace() throws ObjectStreamException {
174: try {
175: return new CertPathRep(getType(), getEncoded());
176: } catch (CertificateEncodingException e) {
177: throw new NotSerializableException(Messages.getString(
178: "security.66", e)); //$NON-NLS-1$
179: }
180: }
181:
182: /**
183: * @com.intel.drl.spec_ref
184: */
185: protected static class CertPathRep implements Serializable {
186: /**
187: * @com.intel.drl.spec_ref
188: */
189: private static final long serialVersionUID = 3015633072427920915L;
190: // Standard name of the type of certificates in this path
191: private final String type;
192: // cert path data
193: private final byte[] data;
194:
195: // Force default serialization to use writeUnshared/readUnshared
196: // for cert path data
197: private static final ObjectStreamField[] serialPersistentFields = {
198: new ObjectStreamField("type", String.class), //$NON-NLS-1$
199: new ObjectStreamField("data", byte[].class, true) //$NON-NLS-1$
200: };
201:
202: /**
203: * @com.intel.drl.spec_ref
204: */
205: protected CertPathRep(String type, byte[] data) {
206: this .type = type;
207: this .data = data;
208: }
209:
210: /**
211: * @com.intel.drl.spec_ref
212: */
213: protected Object readResolve() throws ObjectStreamException {
214: try {
215: CertificateFactory cf = CertificateFactory
216: .getInstance(type);
217: return cf.generateCertPath(new ByteArrayInputStream(
218: data));
219: } catch (Throwable t) {
220: throw new NotSerializableException(Messages.getString(
221: "security.67", t)); //$NON-NLS-1$
222: }
223: }
224: }
225: }
|