1 /*
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.security.cert;
27
28 import java.io.InvalidObjectException;
29 import java.io.IOException;
30 import java.io.ObjectInputStream;
31 import java.security.GeneralSecurityException;
32
33 /**
34 * An exception indicating one of a variety of problems encountered when
35 * validating a certification path.
36 * <p>
37 * A <code>CertPathValidatorException</code> provides support for wrapping
38 * exceptions. The {@link #getCause getCause} method returns the throwable,
39 * if any, that caused this exception to be thrown.
40 * <p>
41 * A <code>CertPathValidatorException</code> may also include the
42 * certification path that was being validated when the exception was thrown,
43 * the index of the certificate in the certification path that caused the
44 * exception to be thrown, and the reason that caused the failure. Use the
45 * {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and
46 * {@link #getReason getReason} methods to retrieve this information.
47 *
48 * <p>
49 * <b>Concurrent Access</b>
50 * <p>
51 * Unless otherwise specified, the methods defined in this class are not
52 * thread-safe. Multiple threads that need to access a single
53 * object concurrently should synchronize amongst themselves and
54 * provide the necessary locking. Multiple threads each manipulating
55 * separate objects need not synchronize.
56 *
57 * @see CertPathValidator
58 *
59 * @since 1.4
60 * @author Yassir Elley
61 */
62 public class CertPathValidatorException extends GeneralSecurityException {
63
64 private static final long serialVersionUID = -3083180014971893139L;
65
66 /**
67 * @serial the index of the certificate in the certification path
68 * that caused the exception to be thrown
69 */
70 private int index = -1;
71
72 /**
73 * @serial the <code>CertPath</code> that was being validated when
74 * the exception was thrown
75 */
76 private CertPath certPath;
77
78 /**
79 * @serial the reason the validation failed
80 */
81 private Reason reason = BasicReason.UNSPECIFIED;
82
83 /**
84 * Creates a <code>CertPathValidatorException</code> with
85 * no detail message.
86 */
87 public CertPathValidatorException() {
88 this(null, null);
89 }
90
91 /**
92 * Creates a <code>CertPathValidatorException</code> with the given
93 * detail message. A detail message is a <code>String</code> that
94 * describes this particular exception.
95 *
96 * @param msg the detail message
97 */
98 public CertPathValidatorException(String msg) {
99 this(msg, null);
100 }
101
102 /**
103 * Creates a <code>CertPathValidatorException</code> that wraps the
104 * specified throwable. This allows any exception to be converted into a
105 * <code>CertPathValidatorException</code>, while retaining information
106 * about the wrapped exception, which may be useful for debugging. The
107 * detail message is set to (<code>cause==null ? null : cause.toString()
108 * </code>) (which typically contains the class and detail message of
109 * cause).
110 *
111 * @param cause the cause (which is saved for later retrieval by the
112 * {@link #getCause getCause()} method). (A <code>null</code> value is
113 * permitted, and indicates that the cause is nonexistent or unknown.)
114 */
115 public CertPathValidatorException(Throwable cause) {
116 this((cause == null ? null : cause.toString()), cause);
117 }
118
119 /**
120 * Creates a <code>CertPathValidatorException</code> with the specified
121 * detail message and cause.
122 *
123 * @param msg the detail message
124 * @param cause the cause (which is saved for later retrieval by the
125 * {@link #getCause getCause()} method). (A <code>null</code> value is
126 * permitted, and indicates that the cause is nonexistent or unknown.)
127 */
128 public CertPathValidatorException(String msg, Throwable cause) {
129 this(msg, cause, null, -1);
130 }
131
132 /**
133 * Creates a <code>CertPathValidatorException</code> with the specified
134 * detail message, cause, certification path, and index.
135 *
136 * @param msg the detail message (or <code>null</code> if none)
137 * @param cause the cause (or <code>null</code> if none)
138 * @param certPath the certification path that was in the process of
139 * being validated when the error was encountered
140 * @param index the index of the certificate in the certification path
141 * that caused the error (or -1 if not applicable). Note that
142 * the list of certificates in a <code>CertPath</code> is zero based.
143 * @throws IndexOutOfBoundsException if the index is out of range
144 * <code>(index < -1 || (certPath != null && index >=
145 * certPath.getCertificates().size())</code>
146 * @throws IllegalArgumentException if <code>certPath</code> is
147 * <code>null</code> and <code>index</code> is not -1
148 */
149 public CertPathValidatorException(String msg, Throwable cause,
150 CertPath certPath, int index) {
151 this(msg, cause, certPath, index, BasicReason.UNSPECIFIED);
152 }
153
154 /**
155 * Creates a <code>CertPathValidatorException</code> with the specified
156 * detail message, cause, certification path, index, and reason.
157 *
158 * @param msg the detail message (or <code>null</code> if none)
159 * @param cause the cause (or <code>null</code> if none)
160 * @param certPath the certification path that was in the process of
161 * being validated when the error was encountered
162 * @param index the index of the certificate in the certification path
163 * that caused the error (or -1 if not applicable). Note that
164 * the list of certificates in a <code>CertPath</code> is zero based.
165 * @param reason the reason the validation failed
166 * @throws IndexOutOfBoundsException if the index is out of range
167 * <code>(index < -1 || (certPath != null && index >=
168 * certPath.getCertificates().size())</code>
169 * @throws IllegalArgumentException if <code>certPath</code> is
170 * <code>null</code> and <code>index</code> is not -1
171 * @throws NullPointerException if <code>reason</code> is <code>null</code>
172 *
173 * @since 1.7
174 */
175 public CertPathValidatorException(String msg, Throwable cause,
176 CertPath certPath, int index, Reason reason) {
177 super(msg, cause);
178 if (certPath == null && index != -1) {
179 throw new IllegalArgumentException();
180 }
181 if (index < -1 ||
182 (certPath != null && index >= certPath.getCertificates().size())) {
183 throw new IndexOutOfBoundsException();
184 }
185 if (reason == null) {
186 throw new NullPointerException("reason can't be null");
187 }
188 this.certPath = certPath;
189 this.index = index;
190 this.reason = reason;
191 }
192
193 /**
194 * Returns the certification path that was being validated when
195 * the exception was thrown.
196 *
197 * @return the <code>CertPath</code> that was being validated when
198 * the exception was thrown (or <code>null</code> if not specified)
199 */
200 public CertPath getCertPath() {
201 return this.certPath;
202 }
203
204 /**
205 * Returns the index of the certificate in the certification path
206 * that caused the exception to be thrown. Note that the list of
207 * certificates in a <code>CertPath</code> is zero based. If no
208 * index has been set, -1 is returned.
209 *
210 * @return the index that has been set, or -1 if none has been set
211 */
212 public int getIndex() {
213 return this.index;
214 }
215
216 /**
217 * Returns the reason that the validation failed. The reason is
218 * associated with the index of the certificate returned by
219 * {@link #getIndex}.
220 *
221 * @return the reason that the validation failed, or
222 * <code>BasicReason.UNSPECIFIED</code> if a reason has not been
223 * specified
224 *
225 * @since 1.7
226 */
227 public Reason getReason() {
228 return this.reason;
229 }
230
231 private void readObject(ObjectInputStream stream)
232 throws ClassNotFoundException, IOException {
233 stream.defaultReadObject();
234 if (reason == null) {
235 reason = BasicReason.UNSPECIFIED;
236 }
237 if (certPath == null && index != -1) {
238 throw new InvalidObjectException("certpath is null and index != -1");
239 }
240 if (index < -1 ||
241 (certPath != null && index >= certPath.getCertificates().size())) {
242 throw new InvalidObjectException("index out of range");
243 }
244 }
245
246 /**
247 * The reason the validation algorithm failed.
248 *
249 * @since 1.7
250 */
251 public static interface Reason extends java.io.Serializable { }
252
253
254 /**
255 * The BasicReason enumerates the potential reasons that a certification
256 * path of any type may be invalid.
257 *
258 * @since 1.7
259 */
260 public static enum BasicReason implements Reason {
261 /**
262 * Unspecified reason.
263 */
264 UNSPECIFIED,
265
266 /**
267 * The certificate is expired.
268 */
269 EXPIRED,
270
271 /**
272 * The certificate is not yet valid.
273 */
274 NOT_YET_VALID,
275
276 /**
277 * The certificate is revoked.
278 */
279 REVOKED,
280
281 /**
282 * The revocation status of the certificate could not be determined.
283 */
284 UNDETERMINED_REVOCATION_STATUS,
285
286 /**
287 * The signature is invalid.
288 */
289 INVALID_SIGNATURE,
290
291 /**
292 * The public key or the signature algorithm has been constrained.
293 */
294 ALGORITHM_CONSTRAINED
295 }
296 }