1 /*
   2  * Copyright (c) 1997, 2019, 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      * @throws    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      * @throws    NoSuchAlgorithmException on unsupported signature
 185      * algorithms.
 186      * @throws    InvalidKeyException on incorrect key.
 187      * @throws    NoSuchProviderException if there's no default provider.
 188      * @throws    SignatureException on signature errors.
 189      * @throws    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      * @throws    NoSuchAlgorithmException on unsupported signature
 206      * algorithms.
 207      * @throws    InvalidKeyException on incorrect key.
 208      * @throws    NoSuchProviderException on incorrect provider.
 209      * @throws    SignatureException on signature errors.
 210      * @throws    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      * @throws    NoSuchAlgorithmException on unsupported signature
 233      * algorithms.
 234      * @throws    InvalidKeyException on incorrect key.
 235      * @throws    SignatureException on signature errors.
 236      * @throws    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         String sigAlgName = getSigAlgName();
 243         Signature sig = (sigProvider == null)
 244             ? Signature.getInstance(sigAlgName)
 245             : Signature.getInstance(sigAlgName, sigProvider);
 246 
 247         try {
 248             byte[] paramBytes = getSigAlgParams();
 249             SignatureUtil.initVerifyWithParam(sig, key,
 250                 SignatureUtil.getParamSpec(sigAlgName, paramBytes));
 251         } catch (ProviderException e) {
 252             throw new CRLException(e.getMessage(), e.getCause());
 253         } catch (InvalidAlgorithmParameterException e) {
 254             throw new CRLException(e);
 255         }
 256 
 257         byte[] tbsCRL = getTBSCertList();
 258         sig.update(tbsCRL, 0, tbsCRL.length);
 259 
 260         if (sig.verify(getSignature()) == false) {
 261             throw new SignatureException("Signature does not match.");
 262         }
 263     }
 264 
 265     /**
 266      * Gets the {@code version} (version number) value from the CRL.
 267      * The ASN.1 definition for this is:
 268      * <pre>
 269      * version    Version OPTIONAL,
 270      *             -- if present, must be v2
 271      *
 272      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 273      *             -- v3 does not apply to CRLs but appears for consistency
 274      *             -- with definition of Version for certs
 275      * </pre>
 276      *
 277      * @return the version number, i.e. 1 or 2.
 278      */
 279     public abstract int getVersion();
 280 
 281     /**
 282      * <strong>Denigrated</strong>, replaced by {@linkplain
 283      * #getIssuerX500Principal()}. This method returns the {@code issuer}
 284      * as an implementation specific Principal object, which should not be
 285      * relied upon by portable code.
 286      *
 287      * <p>
 288      * Gets the {@code issuer} (issuer distinguished name) value from
 289      * the CRL. The issuer name identifies the entity that signed (and
 290      * issued) the CRL.
 291      *
 292      * <p>The issuer name field contains an
 293      * X.500 distinguished name (DN).
 294      * The ASN.1 definition for this is:
 295      * <pre>
 296      * issuer    Name
 297      *
 298      * Name ::= CHOICE { RDNSequence }
 299      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 300      * RelativeDistinguishedName ::=
 301      *     SET OF AttributeValueAssertion
 302      *
 303      * AttributeValueAssertion ::= SEQUENCE {
 304      *                               AttributeType,
 305      *                               AttributeValue }
 306      * AttributeType ::= OBJECT IDENTIFIER
 307      * AttributeValue ::= ANY
 308      * </pre>
 309      * The {@code Name} describes a hierarchical name composed of
 310      * attributes,
 311      * such as country name, and corresponding values, such as US.
 312      * The type of the {@code AttributeValue} component is determined by
 313      * the {@code AttributeType}; in general it will be a
 314      * {@code directoryString}. A {@code directoryString} is usually
 315      * one of {@code PrintableString},
 316      * {@code TeletexString} or {@code UniversalString}.
 317      *
 318      * @return a Principal whose name is the issuer distinguished name.
 319      */
 320     public abstract Principal getIssuerDN();
 321 
 322     /**
 323      * Returns the issuer (issuer distinguished name) value from the
 324      * CRL as an {@code X500Principal}.
 325      * <p>
 326      * It is recommended that subclasses override this method.
 327      *
 328      * @return an {@code X500Principal} representing the issuer
 329      *          distinguished name
 330      * @since 1.4
 331      */
 332     public X500Principal getIssuerX500Principal() {
 333         if (issuerPrincipal == null) {
 334             issuerPrincipal = X509CRLImpl.getIssuerX500Principal(this);
 335         }
 336         return issuerPrincipal;
 337     }
 338 
 339     /**
 340      * Gets the {@code thisUpdate} date from the CRL.
 341      * The ASN.1 definition for this is:
 342      * <pre>
 343      * thisUpdate   ChoiceOfTime
 344      * ChoiceOfTime ::= CHOICE {
 345      *     utcTime        UTCTime,
 346      *     generalTime    GeneralizedTime }
 347      * </pre>
 348      *
 349      * @return the {@code thisUpdate} date from the CRL.
 350      */
 351     public abstract Date getThisUpdate();
 352 
 353     /**
 354      * Gets the {@code nextUpdate} date from the CRL.
 355      *
 356      * @return the {@code nextUpdate} date from the CRL, or null if
 357      * not present.
 358      */
 359     public abstract Date getNextUpdate();
 360 
 361     /**
 362      * Gets the CRL entry, if any, with the given certificate serialNumber.
 363      *
 364      * @param serialNumber the serial number of the certificate for which a CRL entry
 365      * is to be looked up
 366      * @return the entry with the given serial number, or null if no such entry
 367      * exists in this CRL.
 368      * @see X509CRLEntry
 369      */
 370     public abstract X509CRLEntry
 371         getRevokedCertificate(BigInteger serialNumber);
 372 
 373     /**
 374      * Get the CRL entry, if any, for the given certificate.
 375      *
 376      * <p>This method can be used to lookup CRL entries in indirect CRLs,
 377      * that means CRLs that contain entries from issuers other than the CRL
 378      * issuer. The default implementation will only return entries for
 379      * certificates issued by the CRL issuer. Subclasses that wish to
 380      * support indirect CRLs should override this method.
 381      *
 382      * @param certificate the certificate for which a CRL entry is to be looked
 383      *   up
 384      * @return the entry for the given certificate, or null if no such entry
 385      *   exists in this CRL.
 386      * @throws    NullPointerException if certificate is null
 387      *
 388      * @since 1.5
 389      */
 390     public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
 391         X500Principal certIssuer = certificate.getIssuerX500Principal();
 392         X500Principal crlIssuer = getIssuerX500Principal();
 393         if (certIssuer.equals(crlIssuer) == false) {
 394             return null;
 395         }
 396         return getRevokedCertificate(certificate.getSerialNumber());
 397     }
 398 
 399     /**
 400      * Gets all the entries from this CRL.
 401      * This returns a Set of X509CRLEntry objects.
 402      *
 403      * @return all the entries or null if there are none present.
 404      * @see X509CRLEntry
 405      */
 406     public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
 407 
 408     /**
 409      * Gets the DER-encoded CRL information, the
 410      * {@code tbsCertList} from this CRL.
 411      * This can be used to verify the signature independently.
 412      *
 413      * @return the DER-encoded CRL information.
 414      * @throws    CRLException if an encoding error occurs.
 415      */
 416     public abstract byte[] getTBSCertList() throws CRLException;
 417 
 418     /**
 419      * Gets the {@code signature} value (the raw signature bits) from
 420      * the CRL.
 421      * The ASN.1 definition for this is:
 422      * <pre>
 423      * signature     BIT STRING
 424      * </pre>
 425      *
 426      * @return the signature.
 427      */
 428     public abstract byte[] getSignature();
 429 
 430     /**
 431      * Gets the signature algorithm name for the CRL
 432      * signature algorithm. An example is the string "SHA256withRSA".
 433      * The ASN.1 definition for this is:
 434      * <pre>
 435      * signatureAlgorithm   AlgorithmIdentifier
 436      *
 437      * AlgorithmIdentifier  ::=  SEQUENCE  {
 438      *     algorithm               OBJECT IDENTIFIER,
 439      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
 440      *                             -- contains a value of the type
 441      *                             -- registered for use with the
 442      *                             -- algorithm object identifier value
 443      * </pre>
 444      *
 445      * <p>The algorithm name is determined from the {@code algorithm}
 446      * OID string.
 447      *
 448      * @return the signature algorithm name.
 449      */
 450     public abstract String getSigAlgName();
 451 
 452     /**
 453      * Gets the signature algorithm OID string from the CRL.
 454      * An OID is represented by a set of nonnegative whole numbers separated
 455      * by periods.
 456      * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
 457      * with DSA signature algorithm defined in
 458      * <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
 459      * Identifiers for the Internet X.509 Public Key Infrastructure Certificate
 460      * and CRL Profile</a>.
 461      *
 462      * <p>See {@link #getSigAlgName() getSigAlgName} for
 463      * relevant ASN.1 definitions.
 464      *
 465      * @return the signature algorithm OID string.
 466      */
 467     public abstract String getSigAlgOID();
 468 
 469     /**
 470      * Gets the DER-encoded signature algorithm parameters from this
 471      * CRL's signature algorithm. In most cases, the signature
 472      * algorithm parameters are null; the parameters are usually
 473      * supplied with the public key.
 474      * If access to individual parameter values is needed then use
 475      * {@link java.security.AlgorithmParameters AlgorithmParameters}
 476      * and instantiate with the name returned by
 477      * {@link #getSigAlgName() getSigAlgName}.
 478      *
 479      * <p>See {@link #getSigAlgName() getSigAlgName} for
 480      * relevant ASN.1 definitions.
 481      *
 482      * @return the DER-encoded signature algorithm parameters, or
 483      *         null if no parameters are present.
 484      */
 485     public abstract byte[] getSigAlgParams();
 486 }