1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.security.cert;
  27 
  28 import java.security.*;
  29 import java.security.spec.*;
  30 
  31 import javax.security.auth.x500.X500Principal;
  32 
  33 import java.math.BigInteger;
  34 import java.util.Date;
  35 import java.util.Set;
  36 import java.util.Arrays;
  37 
  38 import sun.security.x509.X509CRLImpl;
  39 import sun.security.util.SignatureUtil;
  40 
  41 /**
  42  * <p>
  43  * Abstract class for an X.509 Certificate Revocation List (CRL).
  44  * A CRL is a time-stamped list identifying revoked certificates.
  45  * It is signed by a Certificate Authority (CA) and made freely
  46  * available in a public repository.
  47  *
  48  * <p>Each revoked certificate is
  49  * identified in a CRL by its certificate serial number. When a
  50  * certificate-using system uses a certificate (e.g., for verifying a
  51  * remote user's digital signature), that system not only checks the
  52  * certificate signature and validity but also acquires a suitably-
  53  * recent CRL and checks that the certificate serial number is not on
  54  * that CRL.  The meaning of "suitably-recent" may vary with local
  55  * policy, but it usually means the most recently-issued CRL.  A CA
  56  * issues a new CRL on a regular periodic basis (e.g., hourly, daily, or
  57  * weekly).  Entries are added to CRLs as revocations occur, and an
  58  * entry may be removed when the certificate expiration date is reached.
  59  * <p>
  60  * The X.509 v2 CRL format is described below in ASN.1:
  61  * <pre>
  62  * CertificateList  ::=  SEQUENCE  {
  63  *     tbsCertList          TBSCertList,
  64  *     signatureAlgorithm   AlgorithmIdentifier,
  65  *     signature            BIT STRING  }
  66  * </pre>
  67  * <p>
  68  * More information can be found in
  69  * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  70  * Public Key Infrastructure Certificate and CRL Profile</a>.
  71  * <p>
  72  * The ASN.1 definition of {@code tbsCertList} is:
  73  * <pre>
  74  * TBSCertList  ::=  SEQUENCE  {
  75  *     version                 Version OPTIONAL,
  76  *                             -- if present, must be v2
  77  *     signature               AlgorithmIdentifier,
  78  *     issuer                  Name,
  79  *     thisUpdate              ChoiceOfTime,
  80  *     nextUpdate              ChoiceOfTime OPTIONAL,
  81  *     revokedCertificates     SEQUENCE OF SEQUENCE  {
  82  *         userCertificate         CertificateSerialNumber,
  83  *         revocationDate          ChoiceOfTime,
  84  *         crlEntryExtensions      Extensions OPTIONAL
  85  *                                 -- if present, must be v2
  86  *         }  OPTIONAL,
  87  *     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
  88  *                                  -- if present, must be v2
  89  *     }
  90  * </pre>
  91  * <p>
  92  * CRLs are instantiated using a certificate factory. The following is an
  93  * example of how to instantiate an X.509 CRL:
  94  * <pre>{@code
  95  * try (InputStream inStream = new FileInputStream("fileName-of-crl")) {
  96  *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
  97  *     X509CRL crl = (X509CRL)cf.generateCRL(inStream);
  98  * }
  99  * }</pre>
 100  *
 101  * @author Hemma Prafullchandra
 102  * @since 1.2
 103  *
 104  *
 105  * @see CRL
 106  * @see CertificateFactory
 107  * @see X509Extension
 108  */
 109 
 110 public abstract class X509CRL extends CRL implements X509Extension {
 111 
 112     private transient X500Principal issuerPrincipal;
 113 
 114     /**
 115      * Constructor for X.509 CRLs.
 116      */
 117     protected X509CRL() {
 118         super("X.509");
 119     }
 120 
 121     /**
 122      * Compares this CRL for equality with the given
 123      * object. If the {@code other} object is an
 124      * {@code instanceof} {@code X509CRL}, then
 125      * its encoded form is retrieved and compared with the
 126      * encoded form of this CRL.
 127      *
 128      * @param other the object to test for equality with this CRL.
 129      *
 130      * @return true iff the encoded forms of the two CRLs
 131      * match, false otherwise.
 132      */
 133     public boolean equals(Object other) {
 134         if (this == other) {
 135             return true;
 136         }
 137         if (!(other instanceof X509CRL)) {
 138             return false;
 139         }
 140         try {
 141             byte[] thisCRL = X509CRLImpl.getEncodedInternal(this);
 142             byte[] otherCRL = X509CRLImpl.getEncodedInternal((X509CRL)other);
 143 
 144             return Arrays.equals(thisCRL, otherCRL);
 145         } catch (CRLException e) {
 146             return false;
 147         }
 148     }
 149 
 150     /**
 151      * Returns a hashcode value for this CRL from its
 152      * encoded form.
 153      *
 154      * @return the hashcode value.
 155      */
 156     public int hashCode() {
 157         int retval = 0;
 158         try {
 159             byte[] crlData = X509CRLImpl.getEncodedInternal(this);
 160             for (int i = 1; i < crlData.length; i++) {
 161                  retval += crlData[i] * i;
 162             }
 163             return retval;
 164         } catch (CRLException e) {
 165             return retval;
 166         }
 167     }
 168 
 169     /**
 170      * Returns the ASN.1 DER-encoded form of this CRL.
 171      *
 172      * @return the encoded form of this certificate
 173      * @exception CRLException if an encoding error occurs.
 174      */
 175     public abstract byte[] getEncoded()
 176         throws CRLException;
 177 
 178     /**
 179      * Verifies that this CRL was signed using the
 180      * private key that corresponds to the given public key.
 181      *
 182      * @param key the PublicKey used to carry out the verification.
 183      *
 184      * @exception NoSuchAlgorithmException on unsupported signature
 185      * algorithms.
 186      * @exception InvalidKeyException on incorrect key.
 187      * @exception NoSuchProviderException if there's no default provider.
 188      * @exception SignatureException on signature errors.
 189      * @exception CRLException on encoding errors.
 190      */
 191     public abstract void verify(PublicKey key)
 192         throws CRLException,  NoSuchAlgorithmException,
 193         InvalidKeyException, NoSuchProviderException,
 194         SignatureException;
 195 
 196     /**
 197      * Verifies that this CRL was signed using the
 198      * private key that corresponds to the given public key.
 199      * This method uses the signature verification engine
 200      * supplied by the given provider.
 201      *
 202      * @param key the PublicKey used to carry out the verification.
 203      * @param sigProvider the name of the signature provider.
 204      *
 205      * @exception NoSuchAlgorithmException on unsupported signature
 206      * algorithms.
 207      * @exception InvalidKeyException on incorrect key.
 208      * @exception NoSuchProviderException on incorrect provider.
 209      * @exception SignatureException on signature errors.
 210      * @exception CRLException on encoding errors.
 211      */
 212     public abstract void verify(PublicKey key, String sigProvider)
 213         throws CRLException, NoSuchAlgorithmException,
 214         InvalidKeyException, NoSuchProviderException,
 215         SignatureException;
 216 
 217     /**
 218      * Verifies that this CRL was signed using the
 219      * private key that corresponds to the given public key.
 220      * This method uses the signature verification engine
 221      * supplied by the given provider. Note that the specified Provider object
 222      * does not have to be registered in the provider list.
 223      *
 224      * This method was added to version 1.8 of the Java Platform Standard
 225      * Edition. In order to maintain backwards compatibility with existing
 226      * service providers, this method is not {@code abstract}
 227      * and it provides a default implementation.
 228      *
 229      * @param key the PublicKey used to carry out the verification.
 230      * @param sigProvider the signature provider.
 231      *
 232      * @exception NoSuchAlgorithmException on unsupported signature
 233      * algorithms.
 234      * @exception InvalidKeyException on incorrect key.
 235      * @exception SignatureException on signature errors.
 236      * @exception CRLException on encoding errors.
 237      * @since 1.8
 238      */
 239     public void verify(PublicKey key, Provider sigProvider)
 240         throws CRLException, NoSuchAlgorithmException,
 241         InvalidKeyException, SignatureException {
 242         Signature sig = (sigProvider == null)
 243             ? Signature.getInstance(getSigAlgName())
 244             : Signature.getInstance(getSigAlgName(), sigProvider);
 245 
 246         sig.initVerify(key);
 247 
 248         // set parameters after Signature.initSign/initVerify call,
 249         // so the deferred provider selections occur when key is set
 250         try {
 251             SignatureUtil.specialSetParameter(sig, getSigAlgParams());
 252         } catch (ProviderException e) {
 253             throw new CRLException(e.getMessage(), e.getCause());
 254         } catch (InvalidAlgorithmParameterException e) {
 255             throw new CRLException(e);
 256         }
 257 
 258         byte[] tbsCRL = getTBSCertList();
 259         sig.update(tbsCRL, 0, tbsCRL.length);
 260 
 261         if (sig.verify(getSignature()) == false) {
 262             throw new SignatureException("Signature does not match.");
 263         }
 264     }
 265 
 266     /**
 267      * Gets the {@code version} (version number) value from the CRL.
 268      * The ASN.1 definition for this is:
 269      * <pre>
 270      * version    Version OPTIONAL,
 271      *             -- if present, must be v2
 272      *
 273      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 274      *             -- v3 does not apply to CRLs but appears for consistency
 275      *             -- with definition of Version for certs
 276      * </pre>
 277      *
 278      * @return the version number, i.e. 1 or 2.
 279      */
 280     public abstract int getVersion();
 281 
 282     /**
 283      * <strong>Denigrated</strong>, replaced by {@linkplain
 284      * #getIssuerX500Principal()}. This method returns the {@code issuer}
 285      * as an implementation specific Principal object, which should not be
 286      * relied upon by portable code.
 287      *
 288      * <p>
 289      * Gets the {@code issuer} (issuer distinguished name) value from
 290      * the CRL. The issuer name identifies the entity that signed (and
 291      * issued) the CRL.
 292      *
 293      * <p>The issuer name field contains an
 294      * X.500 distinguished name (DN).
 295      * The ASN.1 definition for this is:
 296      * <pre>
 297      * issuer    Name
 298      *
 299      * Name ::= CHOICE { RDNSequence }
 300      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 301      * RelativeDistinguishedName ::=
 302      *     SET OF AttributeValueAssertion
 303      *
 304      * AttributeValueAssertion ::= SEQUENCE {
 305      *                               AttributeType,
 306      *                               AttributeValue }
 307      * AttributeType ::= OBJECT IDENTIFIER
 308      * AttributeValue ::= ANY
 309      * </pre>
 310      * The {@code Name} describes a hierarchical name composed of
 311      * attributes,
 312      * such as country name, and corresponding values, such as US.
 313      * The type of the {@code AttributeValue} component is determined by
 314      * the {@code AttributeType}; in general it will be a
 315      * {@code directoryString}. A {@code directoryString} is usually
 316      * one of {@code PrintableString},
 317      * {@code TeletexString} or {@code UniversalString}.
 318      *
 319      * @return a Principal whose name is the issuer distinguished name.
 320      */
 321     public abstract Principal getIssuerDN();
 322 
 323     /**
 324      * Returns the issuer (issuer distinguished name) value from the
 325      * CRL as an {@code X500Principal}.
 326      * <p>
 327      * It is recommended that subclasses override this method.
 328      *
 329      * @return an {@code X500Principal} representing the issuer
 330      *          distinguished name
 331      * @since 1.4
 332      */
 333     public X500Principal getIssuerX500Principal() {
 334         if (issuerPrincipal == null) {
 335             issuerPrincipal = X509CRLImpl.getIssuerX500Principal(this);
 336         }
 337         return issuerPrincipal;
 338     }
 339 
 340     /**
 341      * Gets the {@code thisUpdate} date from the CRL.
 342      * The ASN.1 definition for this is:
 343      * <pre>
 344      * thisUpdate   ChoiceOfTime
 345      * ChoiceOfTime ::= CHOICE {
 346      *     utcTime        UTCTime,
 347      *     generalTime    GeneralizedTime }
 348      * </pre>
 349      *
 350      * @return the {@code thisUpdate} date from the CRL.
 351      */
 352     public abstract Date getThisUpdate();
 353 
 354     /**
 355      * Gets the {@code nextUpdate} date from the CRL.
 356      *
 357      * @return the {@code nextUpdate} date from the CRL, or null if
 358      * not present.
 359      */
 360     public abstract Date getNextUpdate();
 361 
 362     /**
 363      * Gets the CRL entry, if any, with the given certificate serialNumber.
 364      *
 365      * @param serialNumber the serial number of the certificate for which a CRL entry
 366      * is to be looked up
 367      * @return the entry with the given serial number, or null if no such entry
 368      * exists in this CRL.
 369      * @see X509CRLEntry
 370      */
 371     public abstract X509CRLEntry
 372         getRevokedCertificate(BigInteger serialNumber);
 373 
 374     /**
 375      * Get the CRL entry, if any, for the given certificate.
 376      *
 377      * <p>This method can be used to lookup CRL entries in indirect CRLs,
 378      * that means CRLs that contain entries from issuers other than the CRL
 379      * issuer. The default implementation will only return entries for
 380      * certificates issued by the CRL issuer. Subclasses that wish to
 381      * support indirect CRLs should override this method.
 382      *
 383      * @param certificate the certificate for which a CRL entry is to be looked
 384      *   up
 385      * @return the entry for the given certificate, or null if no such entry
 386      *   exists in this CRL.
 387      * @exception NullPointerException if certificate is null
 388      *
 389      * @since 1.5
 390      */
 391     public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
 392         X500Principal certIssuer = certificate.getIssuerX500Principal();
 393         X500Principal crlIssuer = getIssuerX500Principal();
 394         if (certIssuer.equals(crlIssuer) == false) {
 395             return null;
 396         }
 397         return getRevokedCertificate(certificate.getSerialNumber());
 398     }
 399 
 400     /**
 401      * Gets all the entries from this CRL.
 402      * This returns a Set of X509CRLEntry objects.
 403      *
 404      * @return all the entries or null if there are none present.
 405      * @see X509CRLEntry
 406      */
 407     public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
 408 
 409     /**
 410      * Gets the DER-encoded CRL information, the
 411      * {@code tbsCertList} from this CRL.
 412      * This can be used to verify the signature independently.
 413      *
 414      * @return the DER-encoded CRL information.
 415      * @exception CRLException if an encoding error occurs.
 416      */
 417     public abstract byte[] getTBSCertList() throws CRLException;
 418 
 419     /**
 420      * Gets the {@code signature} value (the raw signature bits) from
 421      * the CRL.
 422      * The ASN.1 definition for this is:
 423      * <pre>
 424      * signature     BIT STRING
 425      * </pre>
 426      *
 427      * @return the signature.
 428      */
 429     public abstract byte[] getSignature();
 430 
 431     /**
 432      * Gets the signature algorithm name for the CRL
 433      * signature algorithm. An example is the string "SHA256withRSA".
 434      * The ASN.1 definition for this is:
 435      * <pre>
 436      * signatureAlgorithm   AlgorithmIdentifier
 437      *
 438      * AlgorithmIdentifier  ::=  SEQUENCE  {
 439      *     algorithm               OBJECT IDENTIFIER,
 440      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
 441      *                             -- contains a value of the type
 442      *                             -- registered for use with the
 443      *                             -- algorithm object identifier value
 444      * </pre>
 445      *
 446      * <p>The algorithm name is determined from the {@code algorithm}
 447      * OID string.
 448      *
 449      * @return the signature algorithm name.
 450      */
 451     public abstract String getSigAlgName();
 452 
 453     /**
 454      * Gets the signature algorithm OID string from the CRL.
 455      * An OID is represented by a set of nonnegative whole numbers separated
 456      * by periods.
 457      * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
 458      * with DSA signature algorithm defined in
 459      * <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
 460      * Identifiers for the Internet X.509 Public Key Infrastructure Certificate
 461      * and CRL Profile</a>.
 462      *
 463      * <p>See {@link #getSigAlgName() getSigAlgName} for
 464      * relevant ASN.1 definitions.
 465      *
 466      * @return the signature algorithm OID string.
 467      */
 468     public abstract String getSigAlgOID();
 469 
 470     /**
 471      * Gets the DER-encoded signature algorithm parameters from this
 472      * CRL's signature algorithm. In most cases, the signature
 473      * algorithm parameters are null; the parameters are usually
 474      * supplied with the public key.
 475      * If access to individual parameter values is needed then use
 476      * {@link java.security.AlgorithmParameters AlgorithmParameters}
 477      * and instantiate with the name returned by
 478      * {@link #getSigAlgName() getSigAlgName}.
 479      *
 480      * <p>See {@link #getSigAlgName() getSigAlgName} for
 481      * relevant ASN.1 definitions.
 482      *
 483      * @return the DER-encoded signature algorithm parameters, or
 484      *         null if no parameters are present.
 485      */
 486     public abstract byte[] getSigAlgParams();
 487 }