/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.security.cert; import java.io.InputStream; import java.lang.Class; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.Security; import java.math.BigInteger; import java.security.AccessController; import java.security.Principal; import java.security.PrivilegedAction; import java.security.PublicKey; import java.util.BitSet; import java.util.Date; /** * Abstract class for X.509 v1 certificates. This provides a standard * way to access all the version 1 attributes of an X.509 certificate. * Attributes that are specific to X.509 v2 or v3 are not available * through this interface. Future API evolution will provide full access to * complete X.509 v3 attributes. *

* The basic X.509 format was defined by * ISO/IEC and ANSI X9 and is described below in ASN.1: *

 * Certificate  ::=  SEQUENCE  {
 *     tbsCertificate       TBSCertificate,
 *     signatureAlgorithm   AlgorithmIdentifier,
 *     signature            BIT STRING  }
 * 
*

* These certificates are widely used to support authentication and * other functionality in Internet security systems. Common applications * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL), * code signing for trusted software distribution, and Secure Electronic * Transactions (SET). *

* These certificates are managed and vouched for by Certificate * Authorities (CAs). CAs are services which create certificates by * placing data in the X.509 standard format and then digitally signing * that data. CAs act as trusted third parties, making introductions * between principals who have no direct knowledge of each other. * CA certificates are either signed by themselves, or by some other * CA such as a "root" CA. *

* The ASN.1 definition of tbsCertificate is: *

 * TBSCertificate  ::=  SEQUENCE  {
 *     version         [0]  EXPLICIT Version DEFAULT v1,
 *     serialNumber         CertificateSerialNumber,
 *     signature            AlgorithmIdentifier,
 *     issuer               Name,
 *     validity             Validity,
 *     subject              Name,
 *     subjectPublicKeyInfo SubjectPublicKeyInfo,
 *     }
 * 
*

* Here is sample code to instantiate an X.509 certificate: *

 * InputStream inStream = new FileInputStream("fileName-of-cert");
 * X509Certificate cert = X509Certificate.getInstance(inStream);
 * inStream.close();
 * 
* OR *
 * byte[] certData = <certificate read from a file, say>
 * X509Certificate cert = X509Certificate.getInstance(certData);
 * 
*

* In either case, the code that instantiates an X.509 certificate * consults the Java security properties file to locate the actual * implementation or instantiates a default implementation. *

* The Java security properties file is located in the file named * <JAVA_HOME>/lib/security/java.security. * <JAVA_HOME> refers to the value of the java.home system property, * and specifies the directory where the JRE is installed. * In the Security properties file, a default implementation * for X.509 v1 may be given such as: *

 * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
 * 
*

* The value of this cert.provider.x509v1 property has to be * changed to instatiate another implementation. If this security * property is not set, a default implementation will be used. * Currently, due to possible security restrictions on access to * Security properties, this value is looked up and cached at class * initialization time and will fallback on a default implementation if * the Security property is not accessible. * *

Note: The classes in the package javax.security.cert * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in * java.security.cert.

* * @author Hemma Prafullchandra * @since 1.4 * @see Certificate * @see java.security.cert.X509Extension */ public abstract class X509Certificate extends Certificate { /* * Constant to lookup in the Security properties file. * In the Security properties file the default implementation * for X.509 v3 is given as: *
     * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
     * 
*/ private static final String X509_PROVIDER = "cert.provider.x509v1"; private static String X509Provider; static { X509Provider = AccessController.doPrivileged( new PrivilegedAction() { public String run() { return Security.getProperty(X509_PROVIDER); } } ); } /** * Instantiates an X509Certificate object, and initializes it with * the data read from the input stream inStream. * The implementation (X509Certificate is an abstract class) is * provided by the class specified as the value of the * cert.provider.x509v1 * property in the security properties file. * *

Note: Only one DER-encoded * certificate is expected to be in the input stream. * Also, all X509Certificate * subclasses must provide a constructor of the form: *

     * public <subClass>(InputStream inStream) ...
     * 
* * @param inStream an input stream with the data to be read to * initialize the certificate. * @return an X509Certificate object initialized with the data * from the input stream. * @exception CertificateException if a class initialization * or certificate parsing error occurs. */ public static final X509Certificate getInstance(InputStream inStream) throws CertificateException { return getInst((Object)inStream); } /** * Instantiates an X509Certificate object, and initializes it with * the specified byte array. * The implementation (X509Certificate is an abstract class) is * provided by the class specified as the value of the * cert.provider.x509v1 * property in the security properties file. * *

Note: All X509Certificate * subclasses must provide a constructor of the form: *

     * public <subClass>(InputStream inStream) ...
     * 
* * @param certData a byte array containing the DER-encoded * certificate. * @return an X509Certificate object initialized with the data * from certData. * @exception CertificateException if a class initialization * or certificate parsing error occurs. */ public static final X509Certificate getInstance(byte[] certData) throws CertificateException { return getInst((Object)certData); } private static final X509Certificate getInst(Object value) throws CertificateException { /* * This turns out not to work for now. To run under JDK1.2 we would * need to call beginPrivileged() but we can't do that and run * under JDK1.1. */ String className = X509Provider; if (className == null || className.length() == 0) { // shouldn't happen, but assume corrupted properties file // provide access to sun implementation className = "com.sun.security.cert.internal.x509.X509V1CertImpl"; } try { Class[] params = null; if (value instanceof InputStream) { params = new Class[] { InputStream.class }; } else if (value instanceof byte[]) { params = new Class[] { value.getClass() }; } else throw new CertificateException("Unsupported argument type"); Class certClass = Class.forName(className); // get the appropriate constructor and instantiate it Constructor cons = certClass.getConstructor(params); // get a new instance Object obj = cons.newInstance(new Object[] {value}); return (X509Certificate)obj; } catch (ClassNotFoundException e) { throw new CertificateException("Could not find class: " + e); } catch (IllegalAccessException e) { throw new CertificateException("Could not access class: " + e); } catch (InstantiationException e) { throw new CertificateException("Problems instantiating: " + e); } catch (InvocationTargetException e) { throw new CertificateException("InvocationTargetException: " + e.getTargetException()); } catch (NoSuchMethodException e) { throw new CertificateException("Could not find class method: " + e.getMessage()); } } /** * Checks that the certificate is currently valid. It is if * the current date and time are within the validity period given in the * certificate. *

* The validity period consists of two date/time values: * the first and last dates (and times) on which the certificate * is valid. It is defined in * ASN.1 as: *

     * validity             Validity

* Validity ::= SEQUENCE { * notBefore CertificateValidityDate, * notAfter CertificateValidityDate }

* CertificateValidityDate ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime } *

* * @exception CertificateExpiredException if the certificate has expired. * @exception CertificateNotYetValidException if the certificate is not * yet valid. */ public abstract void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException; /** * Checks that the specified date is within the certificate's * validity period. In other words, this determines whether the * certificate would be valid at the specified date/time. * * @param date the Date to check against to see if this certificate * is valid at that date/time. * @exception CertificateExpiredException if the certificate has expired * with respect to the date supplied. * @exception CertificateNotYetValidException if the certificate is not * yet valid with respect to the date supplied. * @see #checkValidity() */ public abstract void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException; /** * Gets the version (version number) value from the * certificate. The ASN.1 definition for this is: *
     * version         [0]  EXPLICIT Version DEFAULT v1

* Version ::= INTEGER { v1(0), v2(1), v3(2) } *

* * @return the version number from the ASN.1 encoding, i.e. 0, 1 or 2. */ public abstract int getVersion(); /** * Gets the serialNumber value from the certificate. * The serial number is an integer assigned by the certification * authority to each certificate. It must be unique for each * certificate issued by a given CA (i.e., the issuer name and * serial number identify a unique certificate). * The ASN.1 definition for this is: *
     * serialNumber     CertificateSerialNumber

* * CertificateSerialNumber ::= INTEGER *

* * @return the serial number. */ public abstract BigInteger getSerialNumber(); /** * Gets the issuer (issuer distinguished name) value from * the certificate. The issuer name identifies the entity that signed (and * issued) the certificate. * *

The issuer name field contains an * X.500 distinguished name (DN). * The ASN.1 definition for this is: *

     * issuer    Name

* * Name ::= CHOICE { RDNSequence } * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName * RelativeDistinguishedName ::= * SET OF AttributeValueAssertion * * AttributeValueAssertion ::= SEQUENCE { * AttributeType, * AttributeValue } * AttributeType ::= OBJECT IDENTIFIER * AttributeValue ::= ANY *

* The Name describes a hierarchical name composed of * attributes, such as country name, and corresponding values, such as US. * The type of the AttributeValue component is determined by * the AttributeType; in general it will be a * directoryString. A directoryString is usually * one of PrintableString, * TeletexString or UniversalString. * * @return a Principal whose name is the issuer distinguished name. */ public abstract Principal getIssuerDN(); /** * Gets the subject (subject distinguished name) value * from the certificate. * The ASN.1 definition for this is: *
     * subject    Name
     * 
* *

See {@link #getIssuerDN() getIssuerDN} for Name * and other relevant definitions. * * @return a Principal whose name is the subject name. * @see #getIssuerDN() */ public abstract Principal getSubjectDN(); /** * Gets the notBefore date from the validity period of * the certificate. * The relevant ASN.1 definitions are: *

     * validity             Validity

* * Validity ::= SEQUENCE { * notBefore CertificateValidityDate, * notAfter CertificateValidityDate }

* CertificateValidityDate ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime } *

* * @return the start date of the validity period. * @see #checkValidity() */ public abstract Date getNotBefore(); /** * Gets the notAfter date from the validity period of * the certificate. See {@link #getNotBefore() getNotBefore} * for relevant ASN.1 definitions. * * @return the end date of the validity period. * @see #checkValidity() */ public abstract Date getNotAfter(); /** * Gets the signature algorithm name for the certificate * signature algorithm. An example is the string "SHA-1/DSA". * The ASN.1 definition for this is: *
     * signatureAlgorithm   AlgorithmIdentifier

* AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL } * -- contains a value of the type * -- registered for use with the * -- algorithm object identifier value *

* *

The algorithm name is determined from the algorithm * OID string. * * @return the signature algorithm name. */ public abstract String getSigAlgName(); /** * Gets the signature algorithm OID string from the certificate. * An OID is represented by a set of positive whole numbers separated * by periods. * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 * with DSA signature algorithm, as per the PKIX part I. * *

See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the signature algorithm OID string. */ public abstract String getSigAlgOID(); /** * Gets the DER-encoded signature algorithm parameters from this * certificate's signature algorithm. In most cases, the signature * algorithm parameters are null; the parameters are usually * supplied with the certificate's public key. * *

See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the DER-encoded signature algorithm parameters, or * null if no parameters are present. */ public abstract byte[] getSigAlgParams(); }