/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 Certificate 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();
  }
}
