/* X509Certificate.java --- X.509 Certificate class
   Copyright (C) 1999,2003 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.security.cert;

import java.math.BigInteger;
import java.security.Principal;
import java.util.Date;

/**
 * X509Certificate is the abstract class for X.509 certificates.
 * This provides a stanard class interface for accessing all 
 * the attributes of X.509 certificates.
 *
 * <p>In June 1996, the basic X.509 v3 format was finished by 
 * ISO/IEC and ANSI X.9. The ASN.1 DER format is below:
 *
 * <blockquote><pre>
 * Certificate  ::=  SEQUENCE  {
 *   tbsCertificate       TBSCertificate,
 *   signatureAlgorithm   AlgorithmIdentifier,
 *   signatureValue       BIT STRING  }
 * </pre></blockquote>
 *
 * <p>These certificates are widely used in various Internet 
 * protocols to support authentication. It is used in 
 * Privacy Enhanced Mail (PEM), Transport Layer Security (TLS),
 * Secure Sockets Layer (SSL), code signing for trusted software
 * distribution, and Secure Electronic Transactions (SET).
 *
 * <p>The certificates are managed and vouched for by 
 * <I>Certificate Authorities</I> (CAs). CAs are companies or 
 * groups that create certificates by placing the data in the 
 * X.509 certificate format and signing it with their private
 * key. CAs serve as trusted third parties by certifying that
 * the person or group specified in the certificate is who
 * they say they are. 
 *
 * <p>The ASN.1 defintion for <I>tbsCertificate</I> is
 * 
 * <blockquote><pre>
 * TBSCertificate  ::=  SEQUENCE  {
 *   version         [0]  EXPLICIT Version DEFAULT v1,
 *   serialNumber         CertificateSerialNumber,
 *   signature            AlgorithmIdentifier,
 *   issuer               Name,
 *   validity             Validity,
 *   subject              Name,
 *   subjectPublicKeyInfo SubjectPublicKeyInfo,
 *   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                        -- If present, version shall be v2 or v3
 *   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                        -- If present, version shall be v2 or v3
 *   extensions      [3]  EXPLICIT Extensions OPTIONAL
 *                        -- If present, version shall be v3
 * }
 *
 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 *
 * CertificateSerialNumber  ::=  INTEGER
 *
 * Validity ::= SEQUENCE {
 *   notBefore      Time,
 *   notAfter       Time }
 *
 * Time ::= CHOICE {
 *   utcTime        UTCTime,
 *   generalTime    GeneralizedTime }
 *
 * UniqueIdentifier  ::=  BIT STRING
 *
 * SubjectPublicKeyInfo  ::=  SEQUENCE  {
 *   algorithm            AlgorithmIdentifier,
 *   subjectPublicKey     BIT STRING  }
 *
 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
 *
 * Extension  ::=  SEQUENCE  {
 *   extnID      OBJECT IDENTIFIER,
 *   critical    BOOLEAN DEFAULT FALSE,
 *   extnValue   OCTET STRING  }
 * </pre></blockquote>
 * 
 * Certificates are created with the CertificateFactory.
 *
 * <p>References:
 *
 * <ol>
 * <li>Olivier Dubuisson, Philippe Fouquart (Translator) <i>ASN.1 -
 * Communication between heterogeneous systems</i>, (C) September 2000,
 * Morgan Kaufmann Publishers, ISBN 0-12-6333361-0. Available on-line at
 * <a
 * href="http://www.oss.com/asn1/dubuisson.html">http://www.oss.com/asn1/dubuisson.html</a></li>
 * <li>R. Housley et al, <i><a href="http://www.ietf.org/rfc/rfc3280.txt">RFC
 * 3280: Internet X.509 Public Key Infrastructure Certificate and CRL
 * Profile</a></i>.</li>
 * </ol>
 *
 * @since JDK 1.2
 * @author Mark Benvenuto
 * @author Casey Marshall (rsdio@metastatic.org)
 */
public abstract class X509Certificate
  extends java.security.cert.Certificate  // XXX workaround for gcj bug #17845
  implements X509Extension
{
  private static final long serialVersionUID = -2491127588187038216L;

  /**
   * Constructs a new certificate of the specified type.
   */
  protected X509Certificate()
  {
    super( "X.509" );
  }

  /**
     Checks the validity of the X.509 certificate. It is valid
     if the current date and time are within the period specified
     by the certificate.

     The ASN.1 DER encoding is:

     validity             Validity,

     Validity ::= SEQUENCE {
     notBefore      Time,
     notAfter       Time }

     Time ::= CHOICE {
     utcTime        UTCTime,
     generalTime    GeneralizedTime }

     Consult rfc2459 for more information.

     @throws CertificateExpiredException if the certificate expired
     @throws CertificateNotYetValidException if the certificate is 
     not yet valid
  */
  public abstract void checkValidity()
    throws CertificateExpiredException,
    CertificateNotYetValidException;

  /**
     Checks the validity of the X.509 certificate for the 
     specified time and date. It is valid if the specified 
     date and time are within the period specified by 
     the certificate.

     @throws CertificateExpiredException if the certificate expired 
     based on the date
     @throws CertificateNotYetValidException if the certificate is 
     not yet valid based on the date
  */
  public abstract void checkValidity(Date date)
    throws CertificateExpiredException,
    CertificateNotYetValidException;

  /**
     Returns the version of this certificate.

     The ASN.1 DER encoding is:

     version         [0]  EXPLICIT Version DEFAULT v1,

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

     Consult rfc2459 for more information.

     @return version number of certificate	
  */
  public abstract int getVersion();

  /**
     Gets the serial number for serial Number in
     this Certifcate. It must be a unique number 
     unique other serial numbers from the granting CA.

     The ASN.1 DER encoding is:

     serialNumber         CertificateSerialNumber,

     CertificateSerialNumber  ::=  INTEGER

     Consult rfc2459 for more information.

     @return the serial number for this X509CRLEntry.
  */
  public abstract BigInteger getSerialNumber();

  /**
     Returns the issuer (issuer distinguished name) of the 
     Certificate. The issuer is the entity who signed 
     and issued the Certificate.

     The ASN.1 DER encoding is:

     issuer                  Name,

     Name ::= CHOICE {
     RDNSequence }

     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

     RelativeDistinguishedName ::=
     SET OF AttributeTypeAndValue

     AttributeTypeAndValue ::= SEQUENCE {
     type     AttributeType,
     value    AttributeValue }

     AttributeType ::= OBJECT IDENTIFIER

     AttributeValue ::= ANY DEFINED BY AttributeType

     DirectoryString ::= CHOICE {
     teletexString           TeletexString (SIZE (1..MAX)),
     printableString         PrintableString (SIZE (1..MAX)),
     universalString         UniversalString (SIZE (1..MAX)),
     utf8String              UTF8String (SIZE (1.. MAX)),
     bmpString               BMPString (SIZE (1..MAX)) }

     Consult rfc2459 for more information.

     @return the issuer in the Principal class
  */
  public abstract Principal getIssuerDN();

  /**
     Returns the subject (subject distinguished name) of the 
     Certificate. The subject is the entity who the Certificate
     identifies.

     The ASN.1 DER encoding is:

     subject              Name,

     Consult rfc2459 for more information.

     @return the issuer in the Principal class
  */
  public abstract Principal getSubjectDN();

  /**
     Returns the date that this certificate is not to be used
     before, <I>notBefore</I>.

     The ASN.1 DER encoding is:

     validity             Validity,

     Validity ::= SEQUENCE {
     notBefore      Time,
     notAfter       Time }

     Time ::= CHOICE {
     utcTime        UTCTime,
     generalTime    GeneralizedTime }

     Consult rfc2459 for more information.

     @return the date <I>notBefore</I>
  */
  public abstract Date getNotBefore();

  /**
     Returns the date that this certificate is not to be used
     after, <I>notAfter</I>.

     @return the date <I>notAfter</I>
  */
  public abstract Date getNotAfter();


  /**
     Returns the <I>tbsCertificate</I> from the certificate.

     @return the DER encoded tbsCertificate

     @throws CertificateEncodingException if encoding error occurred
  */
  public abstract byte[] getTBSCertificate() throws CertificateEncodingException;

  /**
     Returns the signature in its raw DER encoded format.

     The ASN.1 DER encoding is:

     signatureValue       BIT STRING

     Consult rfc2459 for more information.

     @return byte array representing signature
  */
  public abstract byte[] getSignature();

  /**
     Returns the signature algorithm used to sign the CRL. 
     An examples is "SHA-1/DSA".

     The ASN.1 DER encoding is:

     signatureAlgorithm   AlgorithmIdentifier,

     AlgorithmIdentifier  ::=  SEQUENCE  {
     algorithm               OBJECT IDENTIFIER,
     parameters              ANY DEFINED BY algorithm OPTIONAL  }

     Consult rfc2459 for more information.

     The algorithm name is determined from the OID.

     @return a string with the signature algorithm name
  */
  public abstract String getSigAlgName();


  /**
     Returns the OID for the signature algorithm used.
     Example "1.2.840.10040.4.3" is return for SHA-1 with DSA.\

     The ASN.1 DER encoding for the example is:

     id-dsa-with-sha1 ID  ::=  {
     iso(1) member-body(2) us(840) x9-57 (10040)
     x9cm(4) 3 }

     Consult rfc2459 for more information.

     @return a string containing the OID.
  */
  public abstract String getSigAlgOID();


  /**
     Returns the AlgorithmParameters in the encoded form
     for the signature algorithm used. 

     If access to the parameters is need, create an 
     instance of AlgorithmParameters.

     @return byte array containing algorithm parameters, null
     if no parameters are present in certificate
  */
  public abstract byte[] getSigAlgParams();


  /**
     Returns the issuer unique ID for this certificate.

     The ASN.1 DER encoding is:

     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
     -- If present, version shall be v2 or v3

     UniqueIdentifier  ::=  BIT STRING
	
     Consult rfc2459 for more information.

     @return bit representation of <I>issuerUniqueID</I>
  */
  public abstract boolean[] getIssuerUniqueID();

  /**
     Returns the subject unique ID for this certificate.

     The ASN.1 DER encoding is:

     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
     -- If present, version shall be v2 or v3

     UniqueIdentifier  ::=  BIT STRING
	
     Consult rfc2459 for more information.

     @return bit representation of <I>subjectUniqueID</I>
  */
  public abstract boolean[] getSubjectUniqueID();

  /**
     Returns a boolean array representing the <I>KeyUsage</I> 
     extension for the certificate. The KeyUsage (OID = 2.5.29.15)
     defines the purpose of the key in the certificate.

     The ASN.1 DER encoding is:

     id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }

     KeyUsage ::= BIT STRING {
     digitalSignature        (0),
     nonRepudiation          (1),
     keyEncipherment         (2),
     dataEncipherment        (3),
     keyAgreement            (4),
     keyCertSign             (5),
     cRLSign                 (6),
     encipherOnly            (7),
     decipherOnly            (8) }

     Consult rfc2459 for more information.

     @return bit representation of <I>KeyUsage</I>
  */
  public abstract boolean[] getKeyUsage();

  /**
     Returns the certificate constraints path length from the
     critical BasicConstraints extension, (OID = 2.5.29.19).	

     The basic constraints extensions is used to determine if 
     the subject of the certificate is a Certificate Authority (CA) 
     and how deep the certification path may exist. The 
     <I>pathLenConstraint</I> only takes affect if <I>cA</I>
     is set to true. "A value of zero indicates that only an 
     end-entity certificate may follow in the path." (rfc2459)
	
     The ASN.1 DER encoding is:

     id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }

     BasicConstraints ::= SEQUENCE {
     cA                      BOOLEAN DEFAULT FALSE,
     pathLenConstraint       INTEGER (0..MAX) OPTIONAL }

     Consult rfc2459 for more information.

     @return the length of the path constraint if BasicConstraints
     is present and cA is TRUE. Otherwise returns -1.
  */
  public abstract int getBasicConstraints();

  // 1.4 instance methods.
  // ------------------------------------------------------------------------

  /**
   * Returns the <code>ExtendedKeyUsage</code> extension of this
   * certificate, or null if there is no extension present. The returned
   * value is a {@link java.util.List} strings representing the object
   * identifiers of the extended key usages. This extension has the OID
   * 2.5.29.37.
   *
   * <p>The ASN.1 definition for this extension is:
   *
   * <blockquote><pre> 
   * ExtendedKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
   *
   * KeyPurposeId ::= OBJECT IDENTIFIER
   * </pre></blockquote>
   *
   * @return The list of extension OIDs, or null if there are none
   * present in this certificate.
   * @throws CertificateParsingException If this extension cannot be
   * parsed from its encoded form.
   */
  public java.util.List getExtendedKeyUsage()
    throws CertificateParsingException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns the alternative names for this certificate's subject (the
   * owner), or null if there are none.
   *
   * <p>This is an X.509 extension with OID 2.5.29.17 and is defined by
   * the ASN.1 construction:
   *
   * <blockquote><pre>
   * SubjectAltNames ::= GeneralNames
   *
   * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
   *
   * GeneralName ::= CHOICE {
   *   otherName                 [0]   OtherName,
   *   rfc822Name                [1]   IA5String,
   *   dNSName                   [2]   IA5String,
   *   x400Address               [3]   ORAddress,
   *   directoryName             [4]   Name,
   *   ediPartyName              [5]   EDIPartyName,
   *   uniformResourceIdentifier [6]   IA5String,
   *   iPAddress                 [7]   OCTET STRING,
   *   registeredID              [8]   OBJECT IDENTIFIER
   * }
   * </pre></blockquote>
   *
   * <p>The returned collection contains one or more two-element Lists,
   * with the first object being an Integer representing the choice
   * above (with value 0 through 8) and the second being an (a) String
   * if the <code>GeneralName</code> is a rfc822Name, dNSName,
   * uniformResourceIdentifier, iPAddress, or registeredID, or (b) a
   * byte array of the DER encoded form for any others.
   *
   * @return The collection of alternative names, or null if there are
   * none.
   * @throws CertificateParsingException If the encoded extension cannot
   * be parsed.
   * @since JDK 1.4
   */
  public java.util.Collection getSubjectAlternativeNames()
    throws CertificateParsingException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns the alternative names for this certificate's issuer, or
   * null if there are none.
   *
   * <p>This is an X.509 extension with OID 2.5.29.18, and is defined by
   * the ASN.1 construction:
   *
   * <blockquote><pre>
   * IssuerAltNames ::= GeneralNames
   * </pre></blockquote>
   *
   * <p>The <code>GeneralNames</code> construct and the form of the
   * returned collection are the same as with {@link
   * #getSubjectAlternativeNames()}.
   *
   * @return The collection of alternative names, or null if there are
   * none.
   * @throws CertificateParsingException If the encoded extension cannot
   * be parsed.
   * @since JDK 1.4
   */
  public java.util.Collection getIssuerAlternativeNames()
    throws CertificateParsingException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns the X.500 distinguished name of this certificate's subject.
   *
   * @return The subject's X.500 distinguished name.
   * @since JDK 1.4
   */
  public javax.security.auth.x500.X500Principal getSubjectX500Principal()
  {
    throw new UnsupportedOperationException();
  }
 
  /**
   * Returns the X.500 distinguished name of this certificate's issuer.
   *
   * @return The issuer's X.500 distinguished name.
   * @since JDK 1.4
   */
  public javax.security.auth.x500.X500Principal getIssuerX500Principal()
  {
    throw new UnsupportedOperationException();
  }
}
