/* X509CRL.java --- X.509 Certificate Revocation List
   Copyright (C) 1999, 2004  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.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.SignatureException;
import java.util.Date;
import java.util.Set;

import javax.security.auth.x500.X500Principal;

/**
   The X509CRL class is the abstract class used to manage
   X.509 Certificate Revocation Lists. The CRL is a list of
   time stamped entries which indicate which lists have been
   revoked. The list is signed by a Certificate Authority (CA)
   and made publically available in a repository.

   Each revoked certificate in the CRL is identified by its
   certificate serial number. When a piece of code uses a
   certificate, the certificates validity is checked by
   validating its signature and determing that it is not
   only a recently acquired CRL. The recently aquired CRL
   is depends on the local policy in affect. The CA issues
   a new CRL periodically and entries are removed as the
   certificate expiration date is reached


   A description of the X.509 v2 CRL follows below from rfc2459.

   "The X.509 v2 CRL syntax is as follows.  For signature calculation,
   the data that is to be signed is ASN.1 DER encoded.  ASN.1 DER
   encoding is a tag, length, value encoding system for each element.

           CertificateList  ::=  SEQUENCE  {
                tbsCertList          TBSCertList,
                signatureAlgorithm   AlgorithmIdentifier,
                signatureValue       BIT STRING  }

           TBSCertList  ::=  SEQUENCE  {
                version                 Version OPTIONAL,
                                     -- if present, shall be v2
                signature               AlgorithmIdentifier,
                issuer                  Name,
                thisUpdate              Time,
                nextUpdate              Time OPTIONAL,
                revokedCertificates     SEQUENCE OF SEQUENCE  {
                     userCertificate         CertificateSerialNumber,
                     revocationDate          Time,
                     crlEntryExtensions      Extensions OPTIONAL
                                                   -- if present, shall be v2
                                          }  OPTIONAL,
                crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
                                                   -- if present, shall be v2
                                          }"

        @author Mark Benvenuto

        @since 1.2
*/
public abstract class X509CRL extends CRL implements X509Extension
{

  /**
     Constructs a new X509CRL.
  */
  protected X509CRL()
  {
    super("X.509");
  }

  /**
     Compares this X509CRL to other. It checks if the
     object if instanceOf X509CRL and then checks if
     the encoded form matches.

     @param other An Object to test for equality

     @return true if equal, false otherwise
  */
  public boolean equals(Object other)
  {
    if( other instanceof X509CRL ) {
      try {
        X509CRL x = (X509CRL) other;
        if( getEncoded().length != x.getEncoded().length )
          return false;

        byte[] b1 = getEncoded();
        byte[] b2 = x.getEncoded();

        for( int i = 0; i < b1.length; i++ )
          if( b1[i] != b2[i] )
            return false;

      } catch( CRLException crle ) {
        return false;
      }
      return true;
    }
    return false;
  }

  /**
     Returns a hash code for this X509CRL in its encoded
     form.

     @return A hash code of this class
  */
  public int hashCode()
  {
    return super.hashCode();
  }

  /**
     Gets the DER ASN.1 encoded format for this X.509 CRL.

     @return byte array containg encoded form

     @throws CRLException if an error occurs
  */
  public abstract byte[] getEncoded() throws CRLException;

  /**
     Verifies that this CRL was properly signed with the
     PublicKey that corresponds to its private key.

     @param key PublicKey to verify with

     @throws CRLException encoding error
     @throws NoSuchAlgorithmException unsupported algorithm
     @throws InvalidKeyException incorrect key
     @throws NoSuchProviderException no provider
     @throws SignatureException signature error
  */
  public abstract void verify(PublicKey key)
    throws CRLException,
    NoSuchAlgorithmException,
    InvalidKeyException,
    NoSuchProviderException,
    SignatureException;

  /**
     Verifies that this CRL was properly signed with the
     PublicKey that corresponds to its private key and uses
     the signature engine provided by the provider.

     @param key PublicKey to verify with
     @param sigProvider Provider to use for signature algorithm

     @throws CRLException encoding error
     @throws NoSuchAlgorithmException unsupported algorithm
     @throws InvalidKeyException incorrect key
     @throws NoSuchProviderException incorrect provider
     @throws SignatureException signature error
  */
  public abstract void verify(PublicKey key,
                              String sigProvider)
    throws CRLException,
    NoSuchAlgorithmException,
    InvalidKeyException,
    NoSuchProviderException,
    SignatureException;

  /**
     Gets the version of this CRL.

     The ASN.1 encoding is:

     version                 Version OPTIONAL,
     -- if present, shall be v2

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

     Consult rfc2459 for more information.

     @return the version number, Ex: 1 or 2
  */
  public abstract int getVersion();

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

     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 thisUpdate date of the CRL.

     The ASN.1 DER encoding is:

     thisUpdate              Time,

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

     Consult rfc2459 for more information.

     @return the thisUpdate date
  */
  public abstract Date getThisUpdate();

  /*
    Gets the nextUpdate field

    The ASN.1 DER encoding is:

    nextUpdate              Time OPTIONAL,

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

    Consult rfc2459 for more information.

    @return the nextUpdate date
  */
  public abstract Date getNextUpdate();

  /**
     Gets the requeste dX509Entry for the specified
     certificate serial number.

     @return a X509CRLEntry representing the X.509 CRL entry
  */
  public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber);

  /**
     Returns a Set of revoked certificates.

     @return a set of revoked certificates.
  */
  public abstract Set<? extends X509CRLEntry> getRevokedCertificates();

  /**
     Returns the DER ASN.1 encoded tbsCertList which is
     the basic information of the list and associated certificates
     in the encoded state. See top for more information.

     The ASN.1 DER encoding is:

     tbsCertList          TBSCertList,

     Consult rfc2459 for more information.

     @return byte array representing tbsCertList
  */
  public abstract byte[] getTBSCertList() throws CRLException;


  /**
     Returns the signature for the CRL.

     The ASN.1 DER encoding is:

     signatureValue       BIT STRING

     Consult rfc2459 for more information.
  */
  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 CRL
  */
  public abstract byte[] getSigAlgParams();

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

  /**
   * Returns the X.500 distinguished name of this CRL's issuer.
   *
   * @return The issuer's X.500 distinguished name.
   * @since JDK 1.4
   */
  public X500Principal getIssuerX500Principal()
  {
    throw new UnsupportedOperationException();
  }
}
