1 /*
2 * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
27 package javax.security.cert;
28
29 import java.io.InputStream;
30 import java.lang.Class;
31 import java.lang.reflect.Constructor;
32 import java.lang.reflect.InvocationTargetException;
33 import java.security.Security;
34
35 import java.math.BigInteger;
36 import java.security.AccessController;
37 import java.security.Principal;
38 import java.security.PrivilegedAction;
39 import java.security.PublicKey;
40 import java.util.BitSet;
41 import java.util.Date;
42
43 /**
44 * Abstract class for X.509 v1 certificates. This provides a standard
45 * way to access all the version 1 attributes of an X.509 certificate.
46 * Attributes that are specific to X.509 v2 or v3 are not available
47 * through this interface. Future API evolution will provide full access to
48 * complete X.509 v3 attributes.
49 * <p>
50 * The basic X.509 format was defined by
51 * ISO/IEC and ANSI X9 and is described below in ASN.1:
52 * <pre>
53 * Certificate ::= SEQUENCE {
54 * tbsCertificate TBSCertificate,
55 * signatureAlgorithm AlgorithmIdentifier,
56 * signature BIT STRING }
57 * </pre>
58 * <p>
59 * These certificates are widely used to support authentication and
60 * other functionality in Internet security systems. Common applications
61 * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL),
62 * code signing for trusted software distribution, and Secure Electronic
63 * Transactions (SET).
64 * <p>
65 * These certificates are managed and vouched for by <em>Certificate
66 * Authorities</em> (CAs). CAs are services which create certificates by
67 * placing data in the X.509 standard format and then digitally signing
68 * that data. CAs act as trusted third parties, making introductions
69 * between principals who have no direct knowledge of each other.
70 * CA certificates are either signed by themselves, or by some other
71 * CA such as a "root" CA.
72 * <p>
73 * The ASN.1 definition of <code>tbsCertificate</code> is:
74 * <pre>
75 * TBSCertificate ::= SEQUENCE {
76 * version [0] EXPLICIT Version DEFAULT v1,
77 * serialNumber CertificateSerialNumber,
78 * signature AlgorithmIdentifier,
79 * issuer Name,
80 * validity Validity,
81 * subject Name,
82 * subjectPublicKeyInfo SubjectPublicKeyInfo,
83 * }
84 * </pre>
85 * <p>
86 * Here is sample code to instantiate an X.509 certificate:
87 * <pre>
88 * InputStream inStream = new FileInputStream("fileName-of-cert");
89 * X509Certificate cert = X509Certificate.getInstance(inStream);
90 * inStream.close();
91 * </pre>
92 * OR
93 * <pre>
94 * byte[] certData = <certificate read from a file, say>
95 * X509Certificate cert = X509Certificate.getInstance(certData);
96 * </pre>
97 * <p>
98 * In either case, the code that instantiates an X.509 certificate
99 * consults the Java security properties file to locate the actual
100 * implementation or instantiates a default implementation.
101 * <p>
102 * The Java security properties file is located in the file named
103 * <JAVA_HOME>/lib/security/java.security.
104 * <JAVA_HOME> refers to the value of the java.home system property,
105 * and specifies the directory where the JRE is installed.
106 * In the Security properties file, a default implementation
107 * for X.509 v1 may be given such as:
108 * <pre>
109 * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
110 * </pre>
111 * <p>
112 * The value of this <code>cert.provider.x509v1</code> property has to be
113 * changed to instatiate another implementation. If this security
114 * property is not set, a default implementation will be used.
115 * Currently, due to possible security restrictions on access to
116 * Security properties, this value is looked up and cached at class
117 * initialization time and will fallback on a default implementation if
118 * the Security property is not accessible.
119 *
120 * <p><em>Note: The classes in the package <code>javax.security.cert</code>
121 * exist for compatibility with earlier versions of the
122 * Java Secure Sockets Extension (JSSE). New applications should instead
123 * use the standard Java SE certificate classes located in
124 * <code>java.security.cert</code>.</em></p>
125 *
126 * @author Hemma Prafullchandra
127 * @since 1.4
128 * @see Certificate
129 * @see java.security.cert.X509Extension
130 */
131 public abstract class X509Certificate extends Certificate {
132
133 /*
134 * Constant to lookup in the Security properties file.
135 * In the Security properties file the default implementation
136 * for X.509 v3 is given as:
137 * <pre>
138 * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
139 * </pre>
140 */
141 private static final String X509_PROVIDER = "cert.provider.x509v1";
142 private static String X509Provider;
143
144 static {
145 X509Provider = AccessController.doPrivileged(
146 new PrivilegedAction<String>() {
147 public String run() {
148 return Security.getProperty(X509_PROVIDER);
149 }
150 }
151 );
152 }
153
154 /**
155 * Instantiates an X509Certificate object, and initializes it with
156 * the data read from the input stream <code>inStream</code>.
157 * The implementation (X509Certificate is an abstract class) is
158 * provided by the class specified as the value of the
159 * <code>cert.provider.x509v1</code>
160 * property in the security properties file.
161 *
162 * <p>Note: Only one DER-encoded
163 * certificate is expected to be in the input stream.
164 * Also, all X509Certificate
165 * subclasses must provide a constructor of the form:
166 * <code><pre>
167 * public <subClass>(InputStream inStream) ...
168 * </pre></code>
169 *
170 * @param inStream an input stream with the data to be read to
171 * initialize the certificate.
172 * @return an X509Certificate object initialized with the data
173 * from the input stream.
174 * @exception CertificateException if a class initialization
175 * or certificate parsing error occurs.
176 */
177 public static final X509Certificate getInstance(InputStream inStream)
178 throws CertificateException {
179 return getInst((Object)inStream);
180 }
181
182 /**
183 * Instantiates an X509Certificate object, and initializes it with
184 * the specified byte array.
185 * The implementation (X509Certificate is an abstract class) is
186 * provided by the class specified as the value of the
187 * <code>cert.provider.x509v1</code>
188 * property in the security properties file.
189 *
190 * <p>Note: All X509Certificate
191 * subclasses must provide a constructor of the form:
192 * <code><pre>
193 * public <subClass>(InputStream inStream) ...
194 * </pre></code>
195 *
196 * @param certData a byte array containing the DER-encoded
197 * certificate.
198 * @return an X509Certificate object initialized with the data
199 * from <code>certData</code>.
200 * @exception CertificateException if a class initialization
201 * or certificate parsing error occurs.
202 */
203 public static final X509Certificate getInstance(byte[] certData)
204 throws CertificateException {
205 return getInst((Object)certData);
206 }
207
208 private static final X509Certificate getInst(Object value)
209 throws CertificateException {
210 /*
211 * This turns out not to work for now. To run under JDK1.2 we would
212 * need to call beginPrivileged() but we can't do that and run
213 * under JDK1.1.
214 */
215 String className = X509Provider;
216 if (className == null || className.length() == 0) {
217 // shouldn't happen, but assume corrupted properties file
218 // provide access to sun implementation
219 className = "com.sun.security.cert.internal.x509.X509V1CertImpl";
220 }
221 try {
222 Class[] params = null;
223 if (value instanceof InputStream) {
224 params = new Class[] { InputStream.class };
225 } else if (value instanceof byte[]) {
226 params = new Class[] { value.getClass() };
227 } else
228 throw new CertificateException("Unsupported argument type");
229 Class<?> certClass = Class.forName(className);
230
231 // get the appropriate constructor and instantiate it
232 Constructor<?> cons = certClass.getConstructor(params);
233
234 // get a new instance
235 Object obj = cons.newInstance(new Object[] {value});
236 return (X509Certificate)obj;
237
238 } catch (ClassNotFoundException e) {
239 throw new CertificateException("Could not find class: " + e);
240 } catch (IllegalAccessException e) {
241 throw new CertificateException("Could not access class: " + e);
242 } catch (InstantiationException e) {
243 throw new CertificateException("Problems instantiating: " + e);
244 } catch (InvocationTargetException e) {
245 throw new CertificateException("InvocationTargetException: "
246 + e.getTargetException());
247 } catch (NoSuchMethodException e) {
248 throw new CertificateException("Could not find class method: "
249 + e.getMessage());
250 }
251 }
252
253 /**
254 * Checks that the certificate is currently valid. It is if
255 * the current date and time are within the validity period given in the
256 * certificate.
257 * <p>
258 * The validity period consists of two date/time values:
259 * the first and last dates (and times) on which the certificate
260 * is valid. It is defined in
261 * ASN.1 as:
262 * <pre>
263 * validity Validity<p>
264 * Validity ::= SEQUENCE {
265 * notBefore CertificateValidityDate,
266 * notAfter CertificateValidityDate }<p>
267 * CertificateValidityDate ::= CHOICE {
268 * utcTime UTCTime,
269 * generalTime GeneralizedTime }
270 * </pre>
271 *
272 * @exception CertificateExpiredException if the certificate has expired.
273 * @exception CertificateNotYetValidException if the certificate is not
274 * yet valid.
275 */
276 public abstract void checkValidity()
277 throws CertificateExpiredException, CertificateNotYetValidException;
278
279 /**
280 * Checks that the specified date is within the certificate's
281 * validity period. In other words, this determines whether the
282 * certificate would be valid at the specified date/time.
283 *
284 * @param date the Date to check against to see if this certificate
285 * is valid at that date/time.
286 * @exception CertificateExpiredException if the certificate has expired
287 * with respect to the <code>date</code> supplied.
288 * @exception CertificateNotYetValidException if the certificate is not
289 * yet valid with respect to the <code>date</code> supplied.
290 * @see #checkValidity()
291 */
292 public abstract void checkValidity(Date date)
293 throws CertificateExpiredException, CertificateNotYetValidException;
294
295 /**
296 * Gets the <code>version</code> (version number) value from the
297 * certificate. The ASN.1 definition for this is:
298 * <pre>
299 * version [0] EXPLICIT Version DEFAULT v1<p>
300 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
301 * </pre>
302 *
303 * @return the version number from the ASN.1 encoding, i.e. 0, 1 or 2.
304 */
305 public abstract int getVersion();
306
307 /**
308 * Gets the <code>serialNumber</code> value from the certificate.
309 * The serial number is an integer assigned by the certification
310 * authority to each certificate. It must be unique for each
311 * certificate issued by a given CA (i.e., the issuer name and
312 * serial number identify a unique certificate).
313 * The ASN.1 definition for this is:
314 * <pre>
315 * serialNumber CertificateSerialNumber<p>
316 *
317 * CertificateSerialNumber ::= INTEGER
318 * </pre>
319 *
320 * @return the serial number.
321 */
322 public abstract BigInteger getSerialNumber();
323
324 /**
325 * Gets the <code>issuer</code> (issuer distinguished name) value from
326 * the certificate. The issuer name identifies the entity that signed (and
327 * issued) the certificate.
328 *
329 * <p>The issuer name field contains an
330 * X.500 distinguished name (DN).
331 * The ASN.1 definition for this is:
332 * <pre>
333 * issuer Name<p>
334 *
335 * Name ::= CHOICE { RDNSequence }
336 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
337 * RelativeDistinguishedName ::=
338 * SET OF AttributeValueAssertion
339 *
340 * AttributeValueAssertion ::= SEQUENCE {
341 * AttributeType,
342 * AttributeValue }
343 * AttributeType ::= OBJECT IDENTIFIER
344 * AttributeValue ::= ANY
345 * </pre>
346 * The <code>Name</code> describes a hierarchical name composed of
347 * attributes, such as country name, and corresponding values, such as US.
348 * The type of the <code>AttributeValue</code> component is determined by
349 * the <code>AttributeType</code>; in general it will be a
350 * <code>directoryString</code>. A <code>directoryString</code> is usually
351 * one of <code>PrintableString</code>,
352 * <code>TeletexString</code> or <code>UniversalString</code>.
353 *
354 * @return a Principal whose name is the issuer distinguished name.
355 */
356 public abstract Principal getIssuerDN();
357
358 /**
359 * Gets the <code>subject</code> (subject distinguished name) value
360 * from the certificate.
361 * The ASN.1 definition for this is:
362 * <pre>
363 * subject Name
364 * </pre>
365 *
366 * <p>See {@link #getIssuerDN() getIssuerDN} for <code>Name</code>
367 * and other relevant definitions.
368 *
369 * @return a Principal whose name is the subject name.
370 * @see #getIssuerDN()
371 */
372 public abstract Principal getSubjectDN();
373
374 /**
375 * Gets the <code>notBefore</code> date from the validity period of
376 * the certificate.
377 * The relevant ASN.1 definitions are:
378 * <pre>
379 * validity Validity<p>
380 *
381 * Validity ::= SEQUENCE {
382 * notBefore CertificateValidityDate,
383 * notAfter CertificateValidityDate }<p>
384 * CertificateValidityDate ::= CHOICE {
385 * utcTime UTCTime,
386 * generalTime GeneralizedTime }
387 * </pre>
388 *
389 * @return the start date of the validity period.
390 * @see #checkValidity()
391 */
392 public abstract Date getNotBefore();
393
394 /**
395 * Gets the <code>notAfter</code> date from the validity period of
396 * the certificate. See {@link #getNotBefore() getNotBefore}
397 * for relevant ASN.1 definitions.
398 *
399 * @return the end date of the validity period.
400 * @see #checkValidity()
401 */
402 public abstract Date getNotAfter();
403
404 /**
405 * Gets the signature algorithm name for the certificate
406 * signature algorithm. An example is the string "SHA-1/DSA".
407 * The ASN.1 definition for this is:
408 * <pre>
409 * signatureAlgorithm AlgorithmIdentifier<p>
410 * AlgorithmIdentifier ::= SEQUENCE {
411 * algorithm OBJECT IDENTIFIER,
412 * parameters ANY DEFINED BY algorithm OPTIONAL }
413 * -- contains a value of the type
414 * -- registered for use with the
415 * -- algorithm object identifier value
416 * </pre>
417 *
418 * <p>The algorithm name is determined from the <code>algorithm</code>
419 * OID string.
420 *
421 * @return the signature algorithm name.
422 */
423 public abstract String getSigAlgName();
424
425 /**
426 * Gets the signature algorithm OID string from the certificate.
427 * An OID is represented by a set of positive whole numbers separated
428 * by periods.
429 * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
430 * with DSA signature algorithm, as per the PKIX part I.
431 *
432 * <p>See {@link #getSigAlgName() getSigAlgName} for
433 * relevant ASN.1 definitions.
434 *
435 * @return the signature algorithm OID string.
436 */
437 public abstract String getSigAlgOID();
438
439 /**
440 * Gets the DER-encoded signature algorithm parameters from this
441 * certificate's signature algorithm. In most cases, the signature
442 * algorithm parameters are null; the parameters are usually
443 * supplied with the certificate's public key.
444 *
445 * <p>See {@link #getSigAlgName() getSigAlgName} for
446 * relevant ASN.1 definitions.
447 *
448 * @return the DER-encoded signature algorithm parameters, or
449 * null if no parameters are present.
450 */
451 public abstract byte[] getSigAlgParams();
452 }